Fixed bug with preare-file-usage in GDrive

added GetDisplayName in FileStorages
This commit is contained in:
Philipp Crocoll 2013-10-27 15:06:57 +01:00
parent 55da547141
commit 42ead57738
16 changed files with 4866 additions and 1927 deletions

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>

View File

@ -195,5 +195,10 @@ namespace keepass2android.Io
{
throw new NotImplementedException();
}
public string GetDisplayName(IOConnectionInfo ioc)
{
return ioc.GetDisplayName();
}
}
}

View File

@ -476,6 +476,11 @@ namespace keepass2android.Io
_cachedStorage.OnActivityResult(activity, requestCode, resultCode, data);
}
public string GetDisplayName(IOConnectionInfo ioc)
{
return _cachedStorage.GetDisplayName(ioc);
}
public string GetBaseVersionHash(IOConnectionInfo ioc)
{

View File

@ -146,6 +146,10 @@ namespace keepass2android.Io
void OnStart(IFileStorageSetupActivity activity);
void OnActivityResult(IFileStorageSetupActivity activity, int requestCode, int resultCode, Intent data);
/// <summary>
/// Converts the given path to a displayable string
/// </summary>
string GetDisplayName(IOConnectionInfo ioc);
}
public interface IWriteTransaction: IDisposable

View File

@ -275,6 +275,11 @@ namespace keepass2android.Io
_jfs.OnActivityResult(((IJavaFileStorageFileStorageSetupActivity) activity), requestCode, resultCode, data);
}
public string GetDisplayName(IOConnectionInfo ioc)
{
return _jfs.GetDisplayName(ioc.Path);
}
private DateTime JavaTimeToCSharp(long javatime)
{
return new DateTime(1970, 1, 1).AddMilliseconds(javatime);

View File

@ -20,7 +20,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<DefineConstants>TRACE;DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>

View File

@ -1,7 +1,6 @@
package keepass2android.javafilestorage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
@ -16,7 +15,6 @@ import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.DropBoxManager.Entry;
import android.util.Log;
import android.widget.Toast;
@ -533,4 +531,9 @@ public class DropboxFileStorage implements JavaFileStorage {
return path.substring(getProtocolId().length()+3);
}
@Override
public String getDisplayName(String path) {
return path;
}
}

View File

@ -5,13 +5,10 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import com.google.api.client.extensions.android.http.AndroidHttp;
@ -31,12 +28,10 @@ import com.google.api.services.drive.model.FileList;
import com.google.api.services.drive.model.ParentReference;
import android.accounts.AccountManager;
import android.accounts.AccountsException;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
@ -54,6 +49,11 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
class InvalidPathException extends Exception
{
/**
*
*/
private static final long serialVersionUID = 8579741509182446681L;
public InvalidPathException() {}
public InvalidPathException(String message)
@ -102,18 +102,30 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
String mAccount;
String mAccountLocalPath; // the path after the "gdrive://account%40%0Agmail.com/"
public GDrivePath()
{
}
public GDrivePath(String path) throws InvalidPathException, IOException
{
setPath(path);
}
private void setPath(String path) throws
public void setPath(String path) throws
InvalidPathException, IOException {
mAccount = extractAccount(path);
mAccountLocalPath = path.substring(getProtocolId().length()+3+encode(mAccount).length()+1);
setPathWithoutVerify(path);
verifyWithRetry();
}
public void setPathWithoutVerify(String path) throws UnsupportedEncodingException, InvalidPathException
{
Log.d(TAG, "setPath: "+path);
mAccount = extractAccount(path);
mAccountLocalPath = path.substring(getProtocolPrefix().length()+encode(mAccount).length()+1);
Log.d(TAG, " mAccount=" + mAccount);
Log.d(TAG, " mAccountLocalPath=" + mAccountLocalPath);
}
public GDrivePath(String parentPath, File fileToAppend) throws UnsupportedEncodingException, FileNotFoundException, IOException, InvalidPathException
{
setPath(parentPath);
@ -154,11 +166,13 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
for (int i=0;i<parts.length;i++)
{
String part = parts[i];
Log.d(TAG, "parsing part " + part);
int indexOfSeparator = part.lastIndexOf(NAME_ID_SEP);
if (indexOfSeparator < 0)
throw new FileNotFoundException("invalid path " + mAccountLocalPath);
String id = part.substring(indexOfSeparator+NAME_ID_SEP.length());
String name = decode(part.substring(0, indexOfSeparator));
Log.d(TAG, " name=" + name);
FileSystemEntryData thisFolder = accountData.mFolderCache.get(id);
if (thisFolder == null)
{
@ -182,13 +196,48 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
private String extractAccount(String path) throws InvalidPathException, UnsupportedEncodingException {
if (!path.startsWith(getProtocolId()+"://"))
if (!path.startsWith(getProtocolPrefix()))
throw new InvalidPathException("Invalid path: "+path);
String pathWithoutProtocol = path.substring(getProtocolId().length()+3);
String pathWithoutProtocol = path.substring(getProtocolPrefix().length());
String accountNameEncoded = pathWithoutProtocol.substring(0, pathWithoutProtocol.indexOf("/"));
return decode(accountNameEncoded);
}
public String getDisplayName()
{
//gdrive://
String displayName = getProtocolPrefix();
//gdrive//me@google.com/
displayName += mAccount;
if (mAccountLocalPath.equals(""))
return displayName;
String[] parts = mAccountLocalPath.split("/");
for (int i=0;i<parts.length;i++)
{
String part = parts[i];
Log.d(TAG, "parsing part " + part);
int indexOfSeparator = part.lastIndexOf(NAME_ID_SEP);
if (indexOfSeparator < 0)
{
//seems invalid, but we're very generous here
displayName += "/"+part;
continue;
}
String name = part.substring(0, indexOfSeparator);
try {
name = decode(name);
} catch (UnsupportedEncodingException e) {
//ignore
}
displayName += "/"+name;
}
return displayName;
}
public String getGDriveId() throws InvalidPathException, UnsupportedEncodingException {
@ -206,7 +255,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
public String getFullPath() throws UnsupportedEncodingException {
return getProtocolId()+"://"+encode(mAccount)+"/"+mAccountLocalPath;
return getProtocolPrefix()+encode(mAccount)+"/"+mAccountLocalPath;
}
public String getAccount() {
@ -214,6 +263,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
};
@ -447,7 +497,6 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
private Exception convertException(Exception e) {
if (UserRecoverableAuthIOException.class.isAssignableFrom(e.getClass()))
{
UserRecoverableAuthIOException ure = (UserRecoverableAuthIOException) e;
//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();
}
@ -547,7 +596,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
Log.d(TAG, "Initialize Account name="+accountName);
initializeAccount(setupAct, accountName);
initializeAccountOrPath(setupAct, accountName);
return;
}
@ -567,7 +616,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
Log.d(TAG, "Account name="+accountName);
initializeAccount(setupAct, accountName);
initializeAccountOrPath(setupAct, accountName);
}
else
{
@ -585,16 +634,36 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
private void initializeAccount(final JavaFileStorage.FileStorageSetupActivity setupAct, final String accountName) {
private void initializeAccountOrPath(final JavaFileStorage.FileStorageSetupActivity setupAct, final String accountNameOrPath) {
final Activity activity = ((Activity)setupAct);
String accountNameTemp;
GDrivePath gdrivePath = null;
if (accountNameOrPath.startsWith(getProtocolPrefix()))
{
gdrivePath = new GDrivePath();
//don't verify yet, we're not yet initialized:
try {
gdrivePath.setPathWithoutVerify(accountNameOrPath);
} catch (Exception e) {
finishWithError((Activity)setupAct, e);
}
accountNameTemp = gdrivePath.getAccount();
}
else
accountNameTemp = accountNameOrPath;
final String accountName = accountNameTemp;
AsyncTask<Object, Void, AsyncTaskResult<String> > task = new AsyncTask<Object, Void, AsyncTaskResult<String>>()
{
@Override
protected AsyncTaskResult<String> doInBackground(Object... arg0) {
try {
if (!mAccountData.containsKey(accountName))
{
AccountData newAccountData = new AccountData();
@ -631,12 +700,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
else
{
Log.e(TAG, "Exception: "+error.toString());
error.printStackTrace();
Intent retData = new Intent();
retData.putExtra(EXTRA_ERROR_MESSAGE, error.getMessage());
activity.setResult(Activity.RESULT_CANCELED, retData);
activity.finish();
finishWithError(activity, error);
}
} else if ( isCancelled()) {
// cancel handling here
@ -650,7 +714,8 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
finishActivityWithSuccess(setupAct);
}
};
}
@ -660,6 +725,20 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
private void finishWithError(final Activity activity,
Exception error) {
Log.e(TAG, "Exception: "+error.toString());
error.printStackTrace();
Intent retData = new Intent();
retData.putExtra(EXTRA_ERROR_MESSAGE, error.getMessage());
activity.setResult(Activity.RESULT_CANCELED, retData);
activity.finish();
};
private HashMap<String,FileSystemEntryData> buildFoldersCache(String accountName) throws IOException {
HashMap<String, FileSystemEntryData> folderCache = new HashMap<String, GoogleDriveFileStorage.FileSystemEntryData>();
@ -701,9 +780,6 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
if (setupActivity.getProcessName().equals(PROCESS_NAME_SELECTFILE))
{
Intent data = new Intent();
if (setupActivity == (null))
Log.d(TAG, "setupActivity is null");
else
if (setupActivity.getState() == null)
Log.d(TAG, "getState is null");
else
@ -727,7 +803,12 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
@Override
public void startSelectFile(JavaFileStorage.FileStorageSetupInitiatorActivity activity, boolean isForSave,
int requestCode) {
((JavaFileStorage.FileStorageSetupInitiatorActivity)(activity)).startSelectFileProcess(getProtocolId()+"://", isForSave, requestCode);
((JavaFileStorage.FileStorageSetupInitiatorActivity)(activity)).startSelectFileProcess(getProtocolPrefix(), isForSave, requestCode);
}
private String getProtocolPrefix() {
return getProtocolId()+"://";
}
@Override
@ -763,28 +844,7 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
if (PROCESS_NAME_FILE_USAGE_SETUP.equals(setupAct.getProcessName()))
{
GoogleAccountCredential credential = createCredential(activity);
final GDrivePath path;
try
{
path = new GDrivePath(setupAct.getPath());
}
catch (Exception e)
{
Intent data = new Intent();
data.putExtra(EXTRA_ERROR_MESSAGE, e.getMessage());
activity.setResult(Activity.RESULT_CANCELED, data);
activity.finish();
return;
}
if (path.getAccount() != null)
{
credential.setSelectedAccountName(path.getAccount());
initializeAccount(setupAct, path.getAccount());
}
initializeAccountOrPath(setupAct, setupAct.getPath());
}
}
@ -808,4 +868,17 @@ public class GoogleDriveFileStorage implements JavaFileStorage {
}
@Override
public String getDisplayName(String path) {
GDrivePath gdrivePath = new GDrivePath();
try {
gdrivePath.setPathWithoutVerify(path);
} catch (Exception e) {
e.printStackTrace();
return path;
}
return gdrivePath.getDisplayName();
}
}

View File

@ -116,6 +116,8 @@ public class FileEntry {
public String getProtocolId();
public String getDisplayName(String path);
public boolean checkForFileChangeFast(String path, String previousFileVersion) throws Exception;
public String getCurrentFileVersionFast(String path);

View File

@ -480,8 +480,8 @@ namespace keepass2android
}
catch (Exception e)
{
Kp2aLog.Log(e.ToString());
throw;
//not nice, but not a catastrophic failure if we can't delete the file:
Kp2aLog.Log("couldn't delete file after failure! " + e.ToString());
}
}
}

View File

@ -509,7 +509,7 @@ namespace keepass2android
}
private void PopulateView() {
SetEditText(Resource.Id.filename, _ioConnection.GetDisplayName());
SetEditText(Resource.Id.filename, App.Kp2a.GetFileStorage(_ioConnection).GetDisplayName(_ioConnection));
SetEditText(Resource.Id.pass_keyfile, _keyFile);
}

View File

@ -60,7 +60,7 @@ namespace keepass2android
.GetBoolean(GetString(Resource.String.RememberRecentFiles_key),
Resources.GetBoolean(Resource.Boolean.RememberRecentFiles_default)))
{
((TextView)FindViewById(Resource.Id.qu_filename)).Text = _ioc.Path;
((TextView)FindViewById(Resource.Id.qu_filename)).Text = App.Kp2a.GetFileStorage(_ioc).GetDisplayName(_ioc);
}
else
{

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
using System;
using Android.App;
using Android.Content;
using Android.Database;
using Android.OS;
using Android.Preferences;
using Android.Runtime;
@ -180,7 +181,29 @@ namespace keepass2android
}
class MyViewBinder: Java.Lang.Object, SimpleCursorAdapter.IViewBinder
{
private Kp2aApp app;
public MyViewBinder(Kp2aApp app)
{
this.app = app;
}
public bool SetViewValue(View view, ICursor cursor, int columnIndex)
{
if (columnIndex == 1)
{
String path = cursor.GetString(columnIndex);
TextView textView = (TextView)view;
IOConnectionInfo ioc = new IOConnectionInfo() {Path = path};
textView.Text = app.GetFileStorage(ioc).GetDisplayName(ioc);
return true;
}
return false;
}
}
private void FillData()
{
@ -201,6 +224,8 @@ namespace keepass2android
Resource.Layout.file_row, filesCursor, from, to);
notes.ViewBinder = new MyViewBinder(App.Kp2a);
ListAdapter = notes;
}
@ -319,9 +344,8 @@ namespace keepass2android
if (filename != null) {
if (filename.StartsWith("file://")) {
filename = filename.Substring(7);
}
filename = Java.Net.URLDecoder.Decode(filename);
}
if (requestCode == Intents.RequestCodeFileBrowseForOpen)
{

View File

@ -26,6 +26,8 @@ namespace keepass2android.fileselect
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.file_storage_setup);
Ioc = new IOConnectionInfo();
PasswordActivity.SetIoConnectionFromIntent(Ioc, Intent);

View File

@ -24,7 +24,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;EXCLUDE_FILECHOOSER;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
<DefineConstants>DEBUG;EXCLUDE_TWOFISH;EXCLUDE_KEYBOARD;EXCLUDE_KEYTRANSFORM;INCLUDE_FILECHOOSER;INCLUDE_JAVAFILESTORAGE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
@ -195,6 +195,9 @@
<AndroidResource Include="Resources\layout\edit_extra_string_dialog.xml">
<SubType>AndroidResource</SubType>
</AndroidResource>
<AndroidResource Include="Resources\layout\file_storage_setup.xml">
<SubType>AndroidResource</SubType>
</AndroidResource>
<None Include="settings\RoundsPreference %28Kopie%29.cs">
<Visible>False</Visible>
</None>