diff --git a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs index 19a85904..b162b6df 100644 --- a/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs +++ b/src/Kp2aBusinessLogic/Io/JavaFileStorage.cs @@ -93,13 +93,31 @@ namespace keepass2android.Io } - private Exception LogAndConvertJavaException(Java.Lang.Exception e) + private Exception LogAndConvertJavaException(Exception e) { Kp2aLog.Log(e.Message); - var ex = new Exception(e.LocalizedMessage ?? - e.Message ?? - _app.GetResourceString(UiStringKey.ErrorOcurred)+e.GetType().Name, e); - return ex; + + if (e is UserInteractionRequiredException) + return e; + //seems like UserInteractionRequiredException is not propagated correctly into the C# world, we can't catch it + // -> rethrow correctly here + // Note: the Contains-check looks a bit broad, but it should be safe + if (e.ToString().Contains("keepass2android.javafilestorage.UserInteractionRequiredException")) + { + throw new UserInteractionRequiredException(); + } + + Java.Lang.Exception exception = e as Java.Lang.Exception; + if (exception != null) + { + var ex = new Exception(exception.LocalizedMessage ?? + e.Message ?? + _app.GetResourceString(UiStringKey.ErrorOcurred) + exception.GetType().Name, e); + return ex; + } + + return e; + } public IWriteTransaction OpenWriteTransaction(IOConnectionInfo ioc, bool useFileTransaction) @@ -241,12 +259,28 @@ namespace keepass2android.Io public void PrepareFileUsage(IFileStorageSetupInitiatorActivity activity, IOConnectionInfo ioc, int requestCode, Boolean alwaysReturnSuccess) { - _jfs.PrepareFileUsage((IJavaFileStorageFileStorageSetupInitiatorActivity)activity, IocToPath(ioc), requestCode, alwaysReturnSuccess); + try + { + _jfs.PrepareFileUsage((IJavaFileStorageFileStorageSetupInitiatorActivity) activity, IocToPath(ioc), requestCode, + alwaysReturnSuccess); + } + catch (Exception e) + { + throw LogAndConvertJavaException(e); + } } public void PrepareFileUsage(Context ctx, IOConnectionInfo ioc) { - _jfs.PrepareFileUsage(ctx, IocToPath(ioc)); + try + { + _jfs.PrepareFileUsage(ctx, IocToPath(ioc)); + } + catch (Exception e) + { + throw LogAndConvertJavaException(e); + } + } public void OnCreate(IFileStorageSetupActivity activity, Bundle savedInstanceState) diff --git a/src/java/JavaFileStorage/bin/javafilestorage.jar b/src/java/JavaFileStorage/bin/javafilestorage.jar index 9c44faa9..54ae0233 100644 Binary files a/src/java/JavaFileStorage/bin/javafilestorage.jar and b/src/java/JavaFileStorage/bin/javafilestorage.jar differ diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java index dcb22052..e66b4533 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/DropboxFileStorage.java @@ -175,7 +175,7 @@ public class DropboxFileStorage extends JavaFileStorageBase { Log.d(TAG, "LoggedIn=false (due to unlink exception)"); setLoggedIn(false); clearKeys(); - return new Exception("Unlinked from Dropbox!", e); + return new UserInteractionRequiredException("Unlinked from Dropbox! User must re-link.", e); } diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java index 25b5018c..b7632242 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/GoogleDriveFileStorage.java @@ -281,13 +281,16 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { @Override public InputStream openFileForRead(String path) throws Exception { + logDebug("openFileForRead..."); GDrivePath gdrivePath = new GDrivePath(path); Drive driveService = getDriveService(gdrivePath.getAccount()); try { File file = getFileForPath(gdrivePath, driveService); - return getFileContent(file, driveService); + InputStream res = getFileContent(file, driveService); + logDebug("openFileForRead ok."); + return res; } catch (Exception e) { @@ -340,15 +343,17 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { @Override public void uploadFile(String path, byte[] data, boolean writeTransactional) throws Exception { - - ByteArrayContent content = new ByteArrayContent(null, data); - GDrivePath gdrivePath = new GDrivePath(path); - Drive driveService = getDriveService(gdrivePath.getAccount()); + logDebug("upload file..."); try { + ByteArrayContent content = new ByteArrayContent(null, data); + GDrivePath gdrivePath = new GDrivePath(path); + Drive driveService = getDriveService(gdrivePath.getAccount()); + File driveFile = getFileForPath(gdrivePath, driveService); getDriveService(gdrivePath.getAccount()).files() .update(driveFile.getId(), driveFile, content).execute(); + logDebug("upload file ok."); } catch (Exception e) { @@ -451,8 +456,11 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { } private Exception convertException(Exception e) { + logDebug("Exception: " + e.toString()); + e.printStackTrace(); if (UserRecoverableAuthIOException.class.isAssignableFrom(e.getClass())) { + logDebug("clearing account data."); //this is not really nice because it removes data from the cache which might still be valid but we don't have the account name here... mAccountData.clear(); } @@ -682,29 +690,37 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { private void initializeAccount(final Context appContext, final String accountName) throws IOException { + logDebug("Init account for " + accountName); if (!mAccountData.containsKey(accountName)) { AccountData newAccountData = new AccountData(); newAccountData.drive = createDriveService(accountName, appContext); mAccountData.put(accountName, newAccountData); logDebug("Added account data for " + accountName); - //try to finish the initialization. If this fails, we throw. - //in case of "Always return true" (inside CachingFileStorage) this means - //we have a partially uninitialized AccountData object. - //We'll try to initialize later in verify() if (e.g.) network is available again. - finishInitialization(newAccountData, accountName); } + AccountData accountData = mAccountData.get(accountName); + //try to finish the initialization. If this fails, we throw. + //in case of "Always return true" (inside CachingFileStorage) this means + //we have a partially uninitialized AccountData object. + //We'll try to initialize later in verify() if (e.g.) network is available again. + finishInitialization(accountData, accountName); } private void finishInitialization(AccountData newAccountData, String accountName) throws IOException { + if (TextUtils.isEmpty(newAccountData.mRootFolderId)) { + logDebug("Finish init account for " + accountName); About about = newAccountData.drive.about().get().execute(); newAccountData.mRootFolderId = about.getRootFolderId(); } + else + { + logDebug("Account for " + accountName + " already fully initialized."); + } } @Override @@ -726,6 +742,7 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { { try { + logDebug("prepareFileUsage " + path + "..."); String accountName; GDrivePath gdrivePath = null; if (path.startsWith(getProtocolPrefix())) @@ -740,9 +757,11 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { accountName = path; initializeAccount(appContext, accountName); + logDebug("prepareFileUsage ok"); } catch (UserRecoverableAuthIOException e) { + logDebug("prepareFileUsage: UserInteractionRequiredException"); throw new UserInteractionRequiredException(e); } @@ -764,6 +783,7 @@ public class GoogleDriveFileStorage extends JavaFileStorageBase { @Override public void onStart(final JavaFileStorage.FileStorageSetupActivity setupAct) { + logDebug("onStart"); Activity activity = (Activity)setupAct; if (PROCESS_NAME_SELECTFILE.equals(setupAct.getProcessName())) diff --git a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/UserInteractionRequiredException.java b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/UserInteractionRequiredException.java index c30d6dbd..4b52a815 100644 --- a/src/java/JavaFileStorage/src/keepass2android/javafilestorage/UserInteractionRequiredException.java +++ b/src/java/JavaFileStorage/src/keepass2android/javafilestorage/UserInteractionRequiredException.java @@ -1,10 +1,8 @@ package keepass2android.javafilestorage; -import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException; - public class UserInteractionRequiredException extends Exception { - public UserInteractionRequiredException(UserRecoverableAuthIOException e) { + public UserInteractionRequiredException(Throwable e) { super(e); } @@ -12,6 +10,10 @@ public class UserInteractionRequiredException extends Exception { } + public UserInteractionRequiredException(String string, Throwable e) { + super(string, e); + } + /** * */