fix build issues related to removal of deprecated OneDrive API jars. onedrive:// is now no longer supported, but has been replaced with onedrive2:// a long time ago already.
This commit is contained in:
		| @@ -1,31 +1,23 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| using Android.App; | ||||
| using Android.Content; | ||||
| using Android.OS; | ||||
| using Android.Runtime; | ||||
| using Android.Views; | ||||
| using Android.Widget; | ||||
| using KeePassLib.Serialization; | ||||
| #if !EXCLUDE_JAVAFILESTORAGE | ||||
| using Keepass2android.Javafilestorage; | ||||
| using Exception = Java.Lang.Exception; | ||||
|  | ||||
| namespace keepass2android.Io | ||||
| { | ||||
| 	public class OneDriveFileStorage: JavaFileStorage | ||||
|     /// <summary> | ||||
|     /// This IFileStorage implementation becomes picked if a user is using a skydrive:// or onedrive:// file. | ||||
|     /// These refer to an old (Java) implementation which was replaced starting in 2019. The successor uses onedrive2:// (see OneDrive2FileStorage) | ||||
|     /// The Java implementation was removed in 2024 when the jar files became unavailable. We are keeping this file to notify any user who haven't updated their | ||||
|     /// file storage within 5 years. | ||||
|     /// This file should be removed around mid 2025. | ||||
|     /// </summary> | ||||
| 	public class OneDriveFileStorage: IFileStorage | ||||
| 	{ | ||||
| 		private const string ClientId = "000000004010C234"; | ||||
|  | ||||
| 		public OneDriveFileStorage(Context ctx, IKp2aApp app) : | ||||
| 			base(new Keepass2android.Javafilestorage.OneDriveStorage(ctx, ClientId), app) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		public override IEnumerable<string> SupportedProtocols | ||||
| 		 | ||||
| 		public IEnumerable<string> SupportedProtocols | ||||
| 		{ | ||||
| 			get | ||||
| 			{ | ||||
| @@ -34,10 +26,146 @@ namespace keepass2android.Io | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	    public override bool UserShouldBackup | ||||
|         private Exception GetDeprecatedMessage() | ||||
|         { | ||||
|             return new Exception( | ||||
|                 "You have opened your file through a deprecated Microsoft API. Please select Change database, Open Database and then select One Drive again."); | ||||
|         } | ||||
|  | ||||
| 	    public bool UserShouldBackup | ||||
| 	    { | ||||
| 	        get { return false; } | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|         public void Delete(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public bool CheckForFileChangeFast(IOConnectionInfo ioc, string previousFileVersion) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string GetCurrentFileVersionFast(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public Stream OpenFileForRead(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string GetFilenameWithoutPathAndExt(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string GetFileExtension(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public bool RequiresCredentials(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void CreateDirectory(IOConnectionInfo ioc, string newDirName) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<FileDescription> ListContents(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public FileDescription GetFileDescription(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public bool RequiresSetup(IOConnectionInfo ioConnection) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string IocToPath(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void StartSelectFile(IFileStorageSetupInitiatorActivity activity, bool isForSave, int requestCode, string protocolId) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode, | ||||
|             bool alwaysReturnSuccess) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void OnResume(IFileStorageSetupActivity activity) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void OnStart(IFileStorageSetupActivity activity) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string GetDisplayName(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public string CreateFilePath(string parent, string newFilename) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public IOConnectionInfo GetParentPath(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public IOConnectionInfo GetFilePath(IOConnectionInfo folderPath, string filename) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public bool IsPermanentLocation(IOConnectionInfo ioc) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|  | ||||
|         public bool IsReadOnly(IOConnectionInfo ioc, OptionalOut<UiStringKey> reason = null) | ||||
|         { | ||||
|             throw GetDeprecatedMessage(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| @@ -4,11 +4,10 @@ android { | ||||
|  | ||||
|     namespace 'keepass2android.javafilestorage' | ||||
|  | ||||
|     compileSdkVersion 33 | ||||
|  | ||||
|     defaultConfig { | ||||
|         minSdkVersion 15 | ||||
|         minSdkVersion 21 | ||||
|         targetSdkVersion 33 | ||||
|         compileSdk 34 | ||||
|     } | ||||
|     buildTypes { | ||||
|         release { | ||||
| @@ -22,6 +21,10 @@ android { | ||||
|         sourceCompatibility 11 | ||||
|         targetCompatibility 11 | ||||
|     } | ||||
|  | ||||
|     packagingOptions { | ||||
|         exclude 'META-INF/DEPENDENCIES' | ||||
|     } | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -31,7 +34,7 @@ NOTE: If you change dependencies here, don't forget to update the jar files in J | ||||
| dependencies { | ||||
|  | ||||
|     implementation 'com.squareup.okhttp3:okhttp:4.10.0-RC1' | ||||
|     implementation 'com.burgstaller:okhttp-digest:2.5' | ||||
|     implementation 'io.github.rburgst:okhttp-digest:2.5' | ||||
|  | ||||
|     implementation 'com.google.http-client:google-http-client-gson:1.20.0' | ||||
|     implementation('com.google.api-client:google-api-client-android:1.30.5') { | ||||
| @@ -43,14 +46,8 @@ dependencies { | ||||
|     implementation 'com.google.api-client:google-api-client-android:1.30.5' | ||||
|  | ||||
|     implementation 'com.google.android.gms:play-services-auth:20.4.0' | ||||
|     //onedrive: | ||||
|     implementation('com.onedrive.sdk:onedrive-sdk-android:1.2.0') { | ||||
|         transitive = false | ||||
|     } | ||||
|     implementation 'com.pcloud.sdk:java-core:1.9.1' | ||||
|     implementation 'com.pcloud.sdk:android:1.9.1' | ||||
|     implementation 'com.google.code.gson:gson:2.8.6' | ||||
|     implementation 'com.microsoft.services.msa:msa-auth:0.8.6' | ||||
|     implementation 'com.microsoft.aad:adal:1.14.0' | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,436 +0,0 @@ | ||||
| package keepass2android.javafilestorage; | ||||
|  | ||||
| import android.app.Activity; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.AsyncTask; | ||||
| import android.os.Bundle; | ||||
| import androidx.annotation.NonNull; | ||||
| import android.util.Log; | ||||
|  | ||||
| import com.onedrive.sdk.core.DefaultClientConfig; | ||||
| import com.onedrive.sdk.core.IClientConfig; | ||||
| import com.onedrive.sdk.core.OneDriveErrorCodes; | ||||
| import com.onedrive.sdk.extensions.IItemCollectionPage; | ||||
| import com.onedrive.sdk.extensions.IItemCollectionRequestBuilder; | ||||
| import com.onedrive.sdk.extensions.IOneDriveClient; | ||||
| import com.onedrive.sdk.extensions.Item; | ||||
| import com.onedrive.sdk.extensions.OneDriveClient; | ||||
| import com.onedrive.sdk.http.OneDriveServiceException; | ||||
|  | ||||
| import java.io.FileNotFoundException; | ||||
| import java.io.InputStream; | ||||
| import java.io.UnsupportedEncodingException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * Created by Philipp on 20.11.2016. | ||||
|  */ | ||||
| public class OneDriveStorage extends JavaFileStorageBase | ||||
| { | ||||
|     final IClientConfig oneDriveConfig; | ||||
|     final keepass2android.javafilestorage.onedrive.MyMSAAuthenticator msaAuthenticator; | ||||
|  | ||||
|     IOneDriveClient oneDriveClient; | ||||
|  | ||||
|     public OneDriveStorage(final Context context, final String clientId) { | ||||
|         msaAuthenticator = new keepass2android.javafilestorage.onedrive.MyMSAAuthenticator(context) { | ||||
|             @Override | ||||
|             public String getClientId() { | ||||
|                 return clientId; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String[] getScopes() { | ||||
|                 return new String[] { "offline_access", "onedrive.readwrite" }; | ||||
|             } | ||||
|         }; | ||||
|         oneDriveConfig = DefaultClientConfig.createWithAuthenticator(msaAuthenticator); | ||||
|         initAuthenticator(null); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public boolean requiresSetup(String path) { | ||||
|         return !isConnected(null); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void startSelectFile(FileStorageSetupInitiatorActivity activity, boolean isForSave, int requestCode) { | ||||
|  | ||||
|         initAuthenticator((Activity)activity.getActivity()); | ||||
|  | ||||
|         String path = getProtocolId()+":///"; | ||||
|         Log.d("KP2AJ", "startSelectFile "+path+", connected: "+path); | ||||
| 		if (isConnected(null)) | ||||
| 		{ | ||||
| 			Intent intent = new Intent(); | ||||
| 			intent.putExtra(EXTRA_IS_FOR_SAVE, isForSave); | ||||
| 			intent.putExtra(EXTRA_PATH, path); | ||||
| 			activity.onImmediateResult(requestCode, RESULT_FILECHOOSER_PREPARED, intent); | ||||
| 		} | ||||
| 		else | ||||
|         { | ||||
|             activity.startSelectFileProcess(path, isForSave, requestCode); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private boolean isConnected(Activity activity) { | ||||
|         if (oneDriveClient == null) | ||||
|         { | ||||
|             try | ||||
|             { | ||||
|                 Log.d("KP2AJ", "trying silent login"); | ||||
|                 if (msaAuthenticator.loginSilent() != null) | ||||
|                 { | ||||
|                     Log.d("KP2AJ", "ok: silent login"); | ||||
|  | ||||
|                     oneDriveClient = buildClient(activity); | ||||
|  | ||||
|  | ||||
|                 } | ||||
|                 else Log.d("KP2AJ", "trying silent login failed."); | ||||
|             } | ||||
|             catch (Exception e) | ||||
|             { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|         } | ||||
|         return oneDriveClient != null; | ||||
|     } | ||||
|  | ||||
|     private void initAuthenticator(Activity activity) { | ||||
|         msaAuthenticator.init( | ||||
|                 oneDriveConfig.getExecutors(), | ||||
|                 oneDriveConfig.getHttpProvider(), | ||||
|                 activity, | ||||
|                 oneDriveConfig.getLogger()); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     @Override | ||||
|     public void prepareFileUsage(FileStorageSetupInitiatorActivity activity, String path, int requestCode, boolean alwaysReturnSuccess) { | ||||
|         initAuthenticator((Activity)activity.getActivity()); | ||||
|         if (isConnected((Activity)activity.getActivity())) | ||||
|         { | ||||
|             Intent intent = new Intent(); | ||||
|             intent.putExtra(EXTRA_PATH, path); | ||||
|             activity.onImmediateResult(requestCode, RESULT_FILEUSAGE_PREPARED, intent); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             activity.startFileUsageProcess(path, requestCode, alwaysReturnSuccess); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getProtocolId() { | ||||
|         return "onedrive"; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void prepareFileUsage(Context appContext, String path) throws UserInteractionRequiredException { | ||||
|         if (!isConnected(null)) | ||||
|         { | ||||
|             throw new UserInteractionRequiredException(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onCreate(FileStorageSetupActivity activity, Bundle savedInstanceState) { | ||||
|  | ||||
|         Log.d("KP2AJ", "OnCreate"); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onResume(final FileStorageSetupActivity activity) { | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     private IOneDriveClient buildClient(Activity activity) { | ||||
|  | ||||
|         return new OneDriveClient.Builder() | ||||
|                 .fromConfig(oneDriveConfig) | ||||
|                 .loginAndBuildClient(activity); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     String getPathFromSkydrivePath(String skydrivePath) | ||||
|     { | ||||
|         String path = ""; | ||||
|         if (skydrivePath.equals("")) | ||||
|             return ""; | ||||
|  | ||||
|         String[] parts = skydrivePath.split("/"); | ||||
|  | ||||
|         for (int i = 0; i < parts.length; i++) { | ||||
|             String part = parts[i]; | ||||
|             logDebug("parsing part " + part); | ||||
|             int indexOfSeparator = part.lastIndexOf(NAME_ID_SEP); | ||||
|             if (indexOfSeparator < 0) { | ||||
|                 // seems invalid, but we're very generous here | ||||
|                 path += "/" + part; | ||||
|                 continue; | ||||
|             } | ||||
|             String name = part.substring(0, indexOfSeparator); | ||||
|             try { | ||||
|                 name = decode(name); | ||||
|             } catch (UnsupportedEncodingException e) { | ||||
|                 // ignore | ||||
|             } | ||||
|             path += "/" + name; | ||||
|         } | ||||
|         logDebug("return " +path + ". original was " + skydrivePath); | ||||
|         return path; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     String removeProtocol(String path) throws Exception { | ||||
|         if (path == null) | ||||
|             return null; | ||||
|         if (path.startsWith("skydrive")) | ||||
|             return getPathFromSkydrivePath(path.substring("skydrive://".length())); | ||||
|         return path.substring(getProtocolId().length()+3); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getDisplayName(String path) { | ||||
|  | ||||
|         if (path == null) | ||||
|             return null; | ||||
|         if (path.startsWith("skydrive")) | ||||
|             return getProtocolId()+"://"+getPathFromSkydrivePath(path.substring("skydrive://".length())); | ||||
|  | ||||
|         return path; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getFilename(String path) throws Exception { | ||||
|         return path.substring(path.lastIndexOf("/")+1); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String getCurrentFileVersionFast(String path) { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public InputStream openFileForRead(String path) throws Exception { | ||||
|         try { | ||||
|             path = removeProtocol(path); | ||||
|             logDebug("openFileForRead. Path="+path); | ||||
|             InputStream result = oneDriveClient.getDrive() | ||||
|                     .getRoot() | ||||
|                     .getItemWithPath(path) | ||||
|                     .getContent() | ||||
|                     .buildRequest() | ||||
|                     .get(); | ||||
|             logDebug("ok"); | ||||
|             return result; | ||||
|  | ||||
|         } | ||||
|         catch (OneDriveServiceException e) | ||||
|         { | ||||
|             throw convertException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Exception convertException(OneDriveServiceException e) { | ||||
|         if (e.isError(OneDriveErrorCodes.ItemNotFound)) | ||||
|             return new FileNotFoundException(e.getMessage()); | ||||
|         return e; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception { | ||||
|         try { | ||||
|             path = removeProtocol(path); | ||||
|             oneDriveClient.getDrive() | ||||
|                     .getRoot() | ||||
|                     .getItemWithPath(path) | ||||
|                     .getContent() | ||||
|                     .buildRequest() | ||||
|                     .put(data); | ||||
|         } catch (OneDriveServiceException e) { | ||||
|             throw convertException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String createFolder(String parentPath, String newDirName) throws Exception { | ||||
|         throw new Exception("not implemented."); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public String createFilePath(String parentPath, String newFileName) throws Exception { | ||||
|         String path = parentPath; | ||||
|         if (!path.endsWith("/")) | ||||
|             path = path + "/"; | ||||
|         path = path + newFileName; | ||||
|  | ||||
|         return path; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public List<FileEntry> listFiles(String parentPath) throws Exception { | ||||
|         try { | ||||
|             ArrayList<FileEntry> result = new ArrayList<FileEntry>(); | ||||
|             parentPath = removeProtocol(parentPath); | ||||
|             IItemCollectionPage itemsPage = oneDriveClient.getDrive() | ||||
|                     .getRoot() | ||||
|                     .getItemWithPath(parentPath) | ||||
|                     .getChildren() | ||||
|                     .buildRequest() | ||||
|                     .get(); | ||||
|             if (parentPath.endsWith("/")) | ||||
|                 parentPath = parentPath.substring(0,parentPath.length()-1); | ||||
|             while (true) | ||||
|             { | ||||
|                 List<Item> items = itemsPage.getCurrentPage(); | ||||
|                 if (items.isEmpty()) | ||||
|                     return result; | ||||
|  | ||||
|                 for (Item i: items) | ||||
|                 { | ||||
|                     FileEntry e = getFileEntry(parentPath + "/" + i.name, i); | ||||
|                     Log.d("KP2AJ", e.path); | ||||
|                     result.add(e); | ||||
|                 } | ||||
|                 IItemCollectionRequestBuilder nextPageReqBuilder = itemsPage.getNextPage(); | ||||
|                 if (nextPageReqBuilder == null) | ||||
|                     return result; | ||||
|                 itemsPage = nextPageReqBuilder.buildRequest().get(); | ||||
|  | ||||
|             } | ||||
|         } catch (OneDriveServiceException e) { | ||||
|             throw convertException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @NonNull | ||||
|     private FileEntry getFileEntry(String path, Item i) { | ||||
|         FileEntry e = new FileEntry(); | ||||
|         if (i.size != null) | ||||
|             e.sizeInBytes = i.size; | ||||
|         else if ((i.remoteItem != null) && (i.remoteItem.size != null)) | ||||
|             e.sizeInBytes = i.remoteItem.size; | ||||
|  | ||||
|         e.displayName = i.name; | ||||
|         e.canRead = e.canWrite = true; | ||||
|         e.path = getProtocolId() +"://"+path; | ||||
|         if (i.lastModifiedDateTime != null) | ||||
|             e.lastModifiedTime = i.lastModifiedDateTime.getTimeInMillis(); | ||||
|         else if ((i.remoteItem != null)&&(i.remoteItem.lastModifiedDateTime != null)) | ||||
|             e.lastModifiedTime = i.remoteItem.lastModifiedDateTime.getTimeInMillis(); | ||||
|         e.isDirectory = (i.folder != null) || ((i.remoteItem != null) && (i.remoteItem.folder != null)); | ||||
|         return e; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public FileEntry getFileEntry(String filename) throws Exception { | ||||
|         try { | ||||
|             filename = removeProtocol(filename); | ||||
|             Item item = oneDriveClient.getDrive() | ||||
|                     .getRoot() | ||||
|                     .getItemWithPath(filename) | ||||
|                     .buildRequest() | ||||
|                     .get(); | ||||
|             return getFileEntry(filename, item); | ||||
|         } catch (OneDriveServiceException e) { | ||||
|             throw convertException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void delete(String path) throws Exception { | ||||
|         try { | ||||
|             path = removeProtocol(path); | ||||
|             oneDriveClient.getDrive() | ||||
|                     .getRoot() | ||||
|                     .getItemWithPath(path) | ||||
|                     .buildRequest() | ||||
|                     .delete(); | ||||
|         } catch (OneDriveServiceException e) { | ||||
|             throw convertException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onStart(final FileStorageSetupActivity activity) { | ||||
|         Log.d("KP2AJ", "onStart"); | ||||
|         if (activity.getProcessName().equals(PROCESS_NAME_SELECTFILE)) | ||||
|             activity.getState().putString(EXTRA_PATH, activity.getPath()); | ||||
|  | ||||
|         JavaFileStorage.FileStorageSetupActivity storageSetupAct = activity; | ||||
|  | ||||
|         if (oneDriveClient != null) { | ||||
|             Log.d("KP2AJ", "auth successful"); | ||||
|             try { | ||||
|  | ||||
|                 finishActivityWithSuccess(activity); | ||||
|                 return; | ||||
|  | ||||
|             } catch (Exception e) { | ||||
|                 Log.d("KP2AJ", "finish with error: " + e.toString()); | ||||
|                 finishWithError(activity, e); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         { | ||||
|             Log.d("KP2AJ", "Starting auth"); | ||||
|             new AsyncTask<Object, Object, Object>() { | ||||
|  | ||||
|                 @Override | ||||
|                 protected Object doInBackground(Object... params) { | ||||
|                     try { | ||||
|                         return buildClient((Activity) activity); | ||||
|                     } catch (Exception e) { | ||||
|                         return null; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 @Override | ||||
|                 protected void onPostExecute(Object o) { | ||||
|                     if (o == null) | ||||
|                     { | ||||
|                         Log.i(TAG, "authenticating not successful"); | ||||
|                         Intent data = new Intent(); | ||||
|                         data.putExtra(EXTRA_ERROR_MESSAGE, "authenticating not succesful"); | ||||
|                         ((Activity)activity).setResult(Activity.RESULT_CANCELED, data); | ||||
|                         ((Activity)activity).finish(); | ||||
|  | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         Log.i(TAG, "authenticating successful"); | ||||
|  | ||||
|                         oneDriveClient = (IOneDriveClient) o; | ||||
|                         finishActivityWithSuccess(activity); | ||||
|                     } | ||||
|                 } | ||||
|             }.execute(); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void onActivityResult(FileStorageSetupActivity activity, int requestCode, int resultCode, Intent data) { | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,102 +0,0 @@ | ||||
| package keepass2android.javafilestorage.onedrive; | ||||
|  | ||||
| /** | ||||
|  * Created by Philipp on 22.11.2016. | ||||
|  */ | ||||
|  | ||||
| import com.microsoft.services.msa.LiveConnectSession; | ||||
| import com.onedrive.sdk.authentication.AccountType; | ||||
| import com.onedrive.sdk.authentication.IAccountInfo; | ||||
| import com.onedrive.sdk.authentication.MSAAccountInfo; | ||||
| import com.onedrive.sdk.authentication.MSAAuthenticator; | ||||
| import com.onedrive.sdk.logger.ILogger; | ||||
|  | ||||
| import com.microsoft.services.msa.LiveConnectSession; | ||||
| import com.onedrive.sdk.logger.ILogger; | ||||
|  | ||||
| /** | ||||
|  * Account information for a MSA based account. | ||||
|  */ | ||||
| public class MyMSAAccountInfo implements IAccountInfo { | ||||
|  | ||||
|     /** | ||||
|      * The service root for the OneDrive personal API. | ||||
|      */ | ||||
|     public static final String ONE_DRIVE_PERSONAL_SERVICE_ROOT = "https://api.onedrive.com/v1.0"; | ||||
|  | ||||
|     /** | ||||
|      * The authenticator that can refresh this account. | ||||
|      */ | ||||
|     private final MyMSAAuthenticator mAuthenticator; | ||||
|  | ||||
|     /** | ||||
|      * The session this account is based off of. | ||||
|      */ | ||||
|     private LiveConnectSession mSession; | ||||
|  | ||||
|     /** | ||||
|      * The logger. | ||||
|      */ | ||||
|     private final ILogger mLogger; | ||||
|  | ||||
|     /** | ||||
|      * Creates an MSAAccountInfo object. | ||||
|      * @param authenticator The authenticator that this account info was created from. | ||||
|      * @param liveConnectSession The session this account is based off of. | ||||
|      * @param logger The logger. | ||||
|      */ | ||||
|     public MyMSAAccountInfo(final MyMSAAuthenticator authenticator, | ||||
|                           final LiveConnectSession liveConnectSession, | ||||
|                           final ILogger logger) { | ||||
|         mAuthenticator = authenticator; | ||||
|         mSession = liveConnectSession; | ||||
|         mLogger = logger; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the type of the account. | ||||
|      * @return The MicrosoftAccount account type. | ||||
|      */ | ||||
|     @Override | ||||
|     public AccountType getAccountType() { | ||||
|         return AccountType.MicrosoftAccount; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the access token for requests against the service root. | ||||
|      * @return The access token for requests against the service root. | ||||
|      */ | ||||
|     @Override | ||||
|     public String getAccessToken() { | ||||
|         return mSession.getAccessToken(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the OneDrive service root for this account. | ||||
|      * @return the OneDrive service root for this account. | ||||
|      */ | ||||
|     @Override | ||||
|     public String getServiceRoot() { | ||||
|         return ONE_DRIVE_PERSONAL_SERVICE_ROOT; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Indicates if the account access token is expired and needs to be refreshed. | ||||
|      * @return true if refresh() needs to be called and | ||||
|      *         false if the account is still valid. | ||||
|      */ | ||||
|     @Override | ||||
|     public boolean isExpired() { | ||||
|         return mSession.isExpired(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Refreshes the authentication token for this account info. | ||||
|      */ | ||||
|     @Override | ||||
|     public void refresh() { | ||||
|         mLogger.logDebug("Refreshing access token..."); | ||||
|         final MyMSAAccountInfo newInfo = (MyMSAAccountInfo)mAuthenticator.loginSilent(); | ||||
|         mSession = newInfo.mSession; | ||||
|     } | ||||
| } | ||||
| @@ -1,446 +0,0 @@ | ||||
| package keepass2android.javafilestorage.onedrive; | ||||
|  | ||||
| /** | ||||
|  * Created by Philipp on 22.11.2016. | ||||
|  */ | ||||
| import android.app.Activity; | ||||
| import android.content.Context; | ||||
| import android.content.SharedPreferences; | ||||
| import android.util.Log; | ||||
|  | ||||
| import com.microsoft.onedrivesdk.BuildConfig; | ||||
| import com.microsoft.services.msa.LiveAuthClient; | ||||
| import com.microsoft.services.msa.LiveAuthException; | ||||
| import com.microsoft.services.msa.LiveAuthListener; | ||||
| import com.microsoft.services.msa.LiveConnectSession; | ||||
| import com.microsoft.services.msa.LiveStatus; | ||||
| import com.onedrive.sdk.authentication.ClientAuthenticatorException; | ||||
| import com.onedrive.sdk.authentication.IAccountInfo; | ||||
| import com.onedrive.sdk.authentication.IAuthenticator; | ||||
| import com.onedrive.sdk.authentication.MSAAccountInfo; | ||||
| import com.onedrive.sdk.concurrency.ICallback; | ||||
| import com.onedrive.sdk.core.ClientException; | ||||
| import com.onedrive.sdk.concurrency.SimpleWaiter; | ||||
| import com.onedrive.sdk.concurrency.IExecutors; | ||||
| import com.onedrive.sdk.core.OneDriveErrorCodes; | ||||
| import com.onedrive.sdk.http.IHttpProvider; | ||||
| import com.onedrive.sdk.logger.ILogger; | ||||
|  | ||||
| import java.security.InvalidParameterException; | ||||
| import java.util.Arrays; | ||||
| import java.util.concurrent.atomic.AtomicReference; | ||||
|  | ||||
| /** | ||||
|  * Wrapper around the MSA authentication library. | ||||
|  * https://github.com/MSOpenTech/msa-auth-for-android | ||||
|  */ | ||||
| @SuppressWarnings("ThrowableResultOfMethodCallIgnored") | ||||
| public abstract class MyMSAAuthenticator implements IAuthenticator { | ||||
|  | ||||
|     private final Context mContext; | ||||
|  | ||||
|     public MyMSAAuthenticator(Context context) | ||||
|     { | ||||
|         mContext = context; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The sign in cancellation message. | ||||
|      */ | ||||
|     private static final String SIGN_IN_CANCELLED_MESSAGE = "The user cancelled the login operation."; | ||||
|  | ||||
|     /** | ||||
|      * The preferences for this authenticator. | ||||
|      */ | ||||
|     private static final String MSA_AUTHENTICATOR_PREFS = "MSAAuthenticatorPrefs"; | ||||
|  | ||||
|     /** | ||||
|      * The key for the user id. | ||||
|      */ | ||||
|     private static final String USER_ID_KEY = "userId"; | ||||
|  | ||||
|     /** | ||||
|      * The key for the version code | ||||
|      */ | ||||
|     public static final String VERSION_CODE_KEY = "versionCode"; | ||||
|  | ||||
|     /** | ||||
|      * The default user id | ||||
|      */ | ||||
|     private static final String DEFAULT_USER_ID = "@@defaultUser"; | ||||
|  | ||||
|     /** | ||||
|      * The active user id. | ||||
|      */ | ||||
|     private final AtomicReference<String> mUserId = new AtomicReference<>(); | ||||
|  | ||||
|     /** | ||||
|      * The executors. | ||||
|      */ | ||||
|     private IExecutors mExecutors; | ||||
|  | ||||
|     /** | ||||
|      * Indicates whether this authenticator has been initialized. | ||||
|      */ | ||||
|     private boolean mInitialized; | ||||
|  | ||||
|     /** | ||||
|      * The context UI interactions should happen with. | ||||
|      */ | ||||
|     private Activity mActivity; | ||||
|  | ||||
|     /** | ||||
|      * The logger. | ||||
|      */ | ||||
|     private ILogger mLogger; | ||||
|  | ||||
|     /** | ||||
|      * The client id for this authenticator. | ||||
|      * https://dev.onedrive.com/auth/msa_oauth.htm#to-register-your-app | ||||
|      * @return The client id. | ||||
|      */ | ||||
|     public abstract String getClientId(); | ||||
|  | ||||
|     /** | ||||
|      * The scopes for this application. | ||||
|      * https://dev.onedrive.com/auth/msa_oauth.htm#authentication-scopes | ||||
|      * @return The scopes for this application. | ||||
|      */ | ||||
|     public abstract String[] getScopes(); | ||||
|  | ||||
|     /** | ||||
|      * The live authentication client. | ||||
|      */ | ||||
|     private LiveAuthClient mAuthClient; | ||||
|  | ||||
|     /** | ||||
|      * Initializes the authenticator. | ||||
|      * @param executors The executors to schedule foreground and background tasks. | ||||
|      * @param httpProvider The http provider for sending requests. | ||||
|      * @param activity The activity to create interactive UI on. | ||||
|      * @param logger The logger for diagnostic information. | ||||
|      */ | ||||
|     @Override | ||||
|     public synchronized void init(final IExecutors executors, | ||||
|                                   final IHttpProvider httpProvider, | ||||
|                                   final Activity activity, | ||||
|                                   final ILogger logger) { | ||||
|         mActivity = activity; | ||||
|  | ||||
|         if (mInitialized) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         mExecutors = executors; | ||||
|         mLogger = logger; | ||||
|         mInitialized = true; | ||||
|         mAuthClient = new LiveAuthClient(mContext, getClientId(), Arrays.asList(getScopes())); | ||||
|  | ||||
|         final SharedPreferences prefs = getSharedPreferences(); | ||||
|         mUserId.set(prefs.getString(USER_ID_KEY, null)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts an interactive login asynchronously. | ||||
|      * @param emailAddressHint The hint for the email address during the interactive login. | ||||
|      * @param loginCallback The callback to be called when the login is complete. | ||||
|      */ | ||||
|     @Override | ||||
|     public void login(final String emailAddressHint, final ICallback<IAccountInfo> loginCallback) { | ||||
|         Log.d("KP2AJ", "login()"); | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         if (loginCallback == null) { | ||||
|             throw new InvalidParameterException("loginCallback"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting login async"); | ||||
|  | ||||
|         mExecutors.performOnBackground(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 try { | ||||
|                     mExecutors.performOnForeground(login(emailAddressHint), loginCallback); | ||||
|                 } catch (final ClientException e) { | ||||
|                     mExecutors.performOnForeground(e, loginCallback); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts an interactive login. | ||||
|      * @param emailAddressHint The hint for the email address during the interactive login. | ||||
|      * @return The account info. | ||||
|      * @throws ClientException An exception occurs if the login was unable to complete for any reason. | ||||
|      */ | ||||
|     @Override | ||||
|     public synchronized IAccountInfo login(final String emailAddressHint) throws ClientException { | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting login"); | ||||
|  | ||||
|         final AtomicReference<ClientException> error = new AtomicReference<>(); | ||||
|         final SimpleWaiter waiter = new SimpleWaiter(); | ||||
|  | ||||
|         final LiveAuthListener listener = new LiveAuthListener() { | ||||
|             @Override | ||||
|             public void onAuthComplete(final LiveStatus liveStatus, | ||||
|                                        final LiveConnectSession liveConnectSession, | ||||
|                                        final Object o) { | ||||
|                 if (liveStatus == LiveStatus.NOT_CONNECTED) { | ||||
|                     mLogger.logDebug("Received invalid login failure from silent authentication with MSA, ignoring."); | ||||
|                 } else { | ||||
|                     mLogger.logDebug("Successful interactive login"); | ||||
|                     waiter.signal(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onAuthError(final LiveAuthException e, | ||||
|                                     final Object o) { | ||||
|                 OneDriveErrorCodes code = OneDriveErrorCodes.AuthenticationFailure; | ||||
|                 if (e.getError().equals(SIGN_IN_CANCELLED_MESSAGE)) { | ||||
|                     code = OneDriveErrorCodes.AuthenticationCancelled; | ||||
|                 } | ||||
|  | ||||
|                 error.set(new ClientAuthenticatorException("Unable to login with MSA", e, code)); | ||||
|                 mLogger.logError(error.get().getMessage(), error.get()); | ||||
|                 waiter.signal(); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         mActivity.runOnUiThread(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 mAuthClient.login(mActivity, /* scopes */null, /* user object */ null, emailAddressHint, listener); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         mLogger.logDebug("Waiting for MSA callback"); | ||||
|         waiter.waitForSignal(); | ||||
|  | ||||
|         final ClientException exception = error.get(); | ||||
|         if (exception != null) { | ||||
|             throw exception; | ||||
|         } | ||||
|  | ||||
|         final String userId; | ||||
|         if (emailAddressHint != null) { | ||||
|             userId = emailAddressHint; | ||||
|         } else { | ||||
|             userId = DEFAULT_USER_ID; | ||||
|         } | ||||
|  | ||||
|         mUserId.set(userId); | ||||
|  | ||||
|         final SharedPreferences prefs = getSharedPreferences(); | ||||
|         prefs.edit() | ||||
|                 .putString(USER_ID_KEY, mUserId.get()) | ||||
|                 .putInt(VERSION_CODE_KEY, BuildConfig.VERSION_CODE) | ||||
|                 .apply(); | ||||
|  | ||||
|         return getAccountInfo(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts a silent login asynchronously. | ||||
|      * @param loginCallback The callback to be called when the login is complete. | ||||
|      */ | ||||
|     @Override | ||||
|     public void loginSilent(final ICallback<IAccountInfo> loginCallback) { | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         if (loginCallback == null) { | ||||
|             throw new InvalidParameterException("loginCallback"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting login silent async"); | ||||
|  | ||||
|         mExecutors.performOnBackground(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 try { | ||||
|                     mExecutors.performOnForeground(loginSilent(), loginCallback); | ||||
|                 } catch (final ClientException e) { | ||||
|                     mExecutors.performOnForeground(e, loginCallback); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Starts a silent login. | ||||
|      * @return The account info. | ||||
|      * @throws ClientException An exception occurs if the login was unable to complete for any reason. | ||||
|      */ | ||||
|     @Override | ||||
|     public synchronized IAccountInfo loginSilent() throws ClientException { | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting login silent"); | ||||
|  | ||||
|         final int userIdStoredMinVersion = 10112; | ||||
|         if (getSharedPreferences().getInt(VERSION_CODE_KEY, 0) >= userIdStoredMinVersion | ||||
|                 && mUserId.get() == null) { | ||||
|             mLogger.logDebug("No login information found for silent authentication"); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         final SimpleWaiter loginSilentWaiter = new SimpleWaiter(); | ||||
|         final AtomicReference<ClientException> error = new AtomicReference<>(); | ||||
|  | ||||
|         final boolean waitForCallback = mAuthClient.loginSilent(new LiveAuthListener() { | ||||
|             @Override | ||||
|             public void onAuthComplete(final LiveStatus liveStatus, | ||||
|                                        final LiveConnectSession liveConnectSession, | ||||
|                                        final Object o) { | ||||
|                 if (liveStatus == LiveStatus.NOT_CONNECTED) { | ||||
|                     error.set(new ClientAuthenticatorException("Failed silent login, interactive login required", | ||||
|                             OneDriveErrorCodes.AuthenticationFailure)); | ||||
|                     mLogger.logError(error.get().getMessage(), error.get()); | ||||
|                 } else { | ||||
|                     mLogger.logDebug("Successful silent login"); | ||||
|                 } | ||||
|                 loginSilentWaiter.signal(); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onAuthError(final LiveAuthException e, | ||||
|                                     final Object o) { | ||||
|                 OneDriveErrorCodes code = OneDriveErrorCodes.AuthenticationFailure; | ||||
|                 if (e.getError().equals(SIGN_IN_CANCELLED_MESSAGE)) { | ||||
|                     code = OneDriveErrorCodes.AuthenticationCancelled; | ||||
|                 } | ||||
|  | ||||
|                 error.set(new ClientAuthenticatorException("Login silent authentication error", e, code)); | ||||
|                 mLogger.logError(error.get().getMessage(), error.get()); | ||||
|                 loginSilentWaiter.signal(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         if (!waitForCallback) { | ||||
|             mLogger.logDebug("MSA silent auth fast-failed"); | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Waiting for MSA callback"); | ||||
|         loginSilentWaiter.waitForSignal(); | ||||
|         final ClientException exception = error.get(); | ||||
|         if (exception != null) { | ||||
|             throw exception; | ||||
|         } | ||||
|  | ||||
|         return getAccountInfo(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Log the current user out. | ||||
|      * @param logoutCallback The callback to be called when the logout is complete. | ||||
|      */ | ||||
|     @Override | ||||
|     public void logout(final ICallback<Void> logoutCallback) { | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         if (logoutCallback == null) { | ||||
|             throw new InvalidParameterException("logoutCallback"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting logout async"); | ||||
|  | ||||
|         mExecutors.performOnBackground(new Runnable() { | ||||
|             @Override | ||||
|             public void run() { | ||||
|                 try { | ||||
|                     logout(); | ||||
|                     mExecutors.performOnForeground((Void) null, logoutCallback); | ||||
|                 } catch (final ClientException e) { | ||||
|                     mExecutors.performOnForeground(e, logoutCallback); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Log the current user out. | ||||
|      * @throws ClientException An exception occurs if the logout was unable to complete for any reason. | ||||
|      */ | ||||
|     @Override | ||||
|     public synchronized void logout() throws ClientException { | ||||
|         if (!mInitialized) { | ||||
|             throw new IllegalStateException("init must be called"); | ||||
|         } | ||||
|  | ||||
|         mLogger.logDebug("Starting logout"); | ||||
|  | ||||
|         final SimpleWaiter logoutWaiter = new SimpleWaiter(); | ||||
|         final AtomicReference<ClientException> error = new AtomicReference<>(); | ||||
|         mAuthClient.logout(new LiveAuthListener() { | ||||
|             @Override | ||||
|             public void onAuthComplete(final LiveStatus liveStatus, | ||||
|                                        final LiveConnectSession liveConnectSession, | ||||
|                                        final Object o) { | ||||
|                 mLogger.logDebug("Logout completed"); | ||||
|                 logoutWaiter.signal(); | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void onAuthError(final LiveAuthException e, final Object o) { | ||||
|                 error.set(new ClientAuthenticatorException("MSA Logout failed", | ||||
|                         e, | ||||
|                         OneDriveErrorCodes.AuthenticationFailure)); | ||||
|                 mLogger.logError(error.get().getMessage(), error.get()); | ||||
|                 logoutWaiter.signal(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         mLogger.logDebug("Waiting for logout to complete"); | ||||
|         logoutWaiter.waitForSignal(); | ||||
|  | ||||
|         mLogger.logDebug("Clearing all MSA Authenticator shared preferences"); | ||||
|         final SharedPreferences prefs = getSharedPreferences(); | ||||
|         prefs.edit() | ||||
|                 .clear() | ||||
|                 .putInt(VERSION_CODE_KEY, BuildConfig.VERSION_CODE) | ||||
|                 .apply(); | ||||
|         mUserId.set(null); | ||||
|  | ||||
|         final ClientException exception = error.get(); | ||||
|         if (exception != null) { | ||||
|             throw exception; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the current account info for this authenticator. | ||||
|      * @return NULL if no account is available. | ||||
|      */ | ||||
|     @Override | ||||
|     public IAccountInfo getAccountInfo() { | ||||
|         final LiveConnectSession session = mAuthClient.getSession(); | ||||
|         if (session == null) { | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return new MyMSAAccountInfo(this, session, mLogger); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets the shared preferences for this authenticator. | ||||
|      * @return The shared preferences. | ||||
|      */ | ||||
|     private SharedPreferences getSharedPreferences() { | ||||
|         return mContext.getSharedPreferences(MSA_AUTHENTICATOR_PREFS, Context.MODE_PRIVATE); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1 +1,2 @@ | ||||
| org.gradle.jvmargs=-Xmx1536m | ||||
| android.useAndroidX=true | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll