add option to sync database after quick-unlocking the database. closes https://github.com/PhilippC/keepass2android/issues/188
This commit is contained in:
@@ -119,7 +119,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache);
|
IFileStorage GetFileStorage(IOConnectionInfo iocInfo, bool allowCache);
|
||||||
|
|
||||||
void TriggerReload(Context context);
|
void TriggerReload(Context context, Action<bool> actionOnResult /*if not null, called when the user selected yes (true) or no (false)*/);
|
||||||
|
|
||||||
|
|
||||||
bool CheckForDuplicateUuids { get; }
|
bool CheckForDuplicateUuids { get; }
|
||||||
|
@@ -51,7 +51,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
if (!MemUtil.ArraysEqual(_app.CurrentDb.KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
|
if (!MemUtil.ArraysEqual(_app.CurrentDb.KpDatabase.HashOfFileOnDisk, hashingRemoteStream.Hash))
|
||||||
{
|
{
|
||||||
_app.TriggerReload(_context);
|
_app.TriggerReload(_context, null);
|
||||||
Finish(true);
|
Finish(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -85,8 +85,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
//only the remote file was modified -> reload database.
|
//only the remote file was modified -> reload database.
|
||||||
//note: it's best to lock the database and do a complete reload here (also better for UI consistency in case something goes wrong etc.)
|
//note: it's best to lock the database and do a complete reload here (also better for UI consistency in case something goes wrong etc.)
|
||||||
_app.TriggerReload(_context);
|
_app.TriggerReload(_context, (bool result) => Finish(result));
|
||||||
Finish(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -28,7 +28,6 @@ using Android.Widget;
|
|||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using KeePassLib.Interfaces;
|
using KeePassLib.Interfaces;
|
||||||
using KeePassLib.Serialization;
|
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
using keepass2android.Io;
|
using keepass2android.Io;
|
||||||
using keepass2android.database.edit;
|
using keepass2android.database.edit;
|
||||||
@@ -42,7 +41,6 @@ using Object = Java.Lang.Object;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class GroupBaseActivity : LockCloseActivity
|
public abstract class GroupBaseActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
public const String KeyEntry = "entry";
|
public const String KeyEntry = "entry";
|
||||||
@@ -1062,7 +1060,7 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_sync:
|
case Resource.Id.menu_sync:
|
||||||
Synchronize();
|
new SyncUtil(this).SynchronizeDatabase(() => { });
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_work_offline:
|
case Resource.Id.menu_work_offline:
|
||||||
@@ -1073,7 +1071,7 @@ namespace keepass2android
|
|||||||
case Resource.Id.menu_work_online:
|
case Resource.Id.menu_work_online:
|
||||||
App.Kp2a.OfflineMode = App.Kp2a.OfflineModePreference = false;
|
App.Kp2a.OfflineMode = App.Kp2a.OfflineModePreference = false;
|
||||||
UpdateOfflineModeMenu();
|
UpdateOfflineModeMenu();
|
||||||
Synchronize();
|
new SyncUtil(this).SynchronizeDatabase(() => { });
|
||||||
return true;
|
return true;
|
||||||
case Resource.Id.menu_open_other_db:
|
case Resource.Id.menu_open_other_db:
|
||||||
AppTask.SetActivityResult(this, KeePass.ExitLoadAnotherDb);
|
AppTask.SetActivityResult(this, KeePass.ExitLoadAnotherDb);
|
||||||
@@ -1096,77 +1094,7 @@ namespace keepass2android
|
|||||||
return base.OnOptionsItemSelected(item);
|
return base.OnOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SyncOtpAuxFile : RunnableOnFinish
|
|
||||||
{
|
|
||||||
private readonly IOConnectionInfo _ioc;
|
|
||||||
|
|
||||||
public SyncOtpAuxFile(Activity activity, IOConnectionInfo ioc)
|
|
||||||
: base(activity,null)
|
|
||||||
{
|
|
||||||
_ioc = ioc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Run()
|
|
||||||
{
|
|
||||||
StatusLogger.UpdateMessage(UiStringKey.SynchronizingOtpAuxFile);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//simply open the file. The file storage does a complete sync.
|
|
||||||
using (App.Kp2a.GetOtpAuxFileStorage(_ioc).OpenFileForRead(_ioc))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Finish(true);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
|
|
||||||
Finish(false, e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Synchronize()
|
|
||||||
{
|
|
||||||
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc);
|
|
||||||
RunnableOnFinish task;
|
|
||||||
OnFinish onFinish = new ActionOnFinish(this, (success, message, activity) =>
|
|
||||||
{
|
|
||||||
if (!String.IsNullOrEmpty(message))
|
|
||||||
Toast.MakeText(activity, message, ToastLength.Long).Show();
|
|
||||||
|
|
||||||
// Tell the adapter to refresh it's list
|
|
||||||
BaseAdapter adapter = (BaseAdapter)((GroupBaseActivity)activity)?.ListAdapter;
|
|
||||||
adapter?.NotifyDataSetChanged();
|
|
||||||
|
|
||||||
if (App.Kp2a.CurrentDb.OtpAuxFileIoc != null)
|
|
||||||
{
|
|
||||||
var task2 = new SyncOtpAuxFile(this, App.Kp2a.CurrentDb.OtpAuxFileIoc);
|
|
||||||
new ProgressTask(App.Kp2a, activity, task2).Run(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (filestorage is CachingFileStorage)
|
|
||||||
{
|
|
||||||
|
|
||||||
task = new SynchronizeCachedDatabase(this, App.Kp2a, onFinish);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
task = new CheckDatabaseForChanges(this, App.Kp2a, onFinish);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var progressTask = new ProgressTask(App.Kp2a, this, task);
|
|
||||||
progressTask.Run();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnBackPressed()
|
public override void OnBackPressed()
|
||||||
{
|
{
|
||||||
|
@@ -212,10 +212,8 @@ namespace keepass2android
|
|||||||
pwd.Text = ExpectedPasswordPart;
|
pwd.Text = ExpectedPasswordPart;
|
||||||
|
|
||||||
btn.PostDelayed(() =>
|
btn.PostDelayed(() =>
|
||||||
{
|
{
|
||||||
|
UnlockAndSyncAndClose();
|
||||||
App.Kp2a.UnlockDatabase();
|
|
||||||
Finish();
|
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
|
|
||||||
@@ -327,20 +325,36 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
var expectedPasswordPart = ExpectedPasswordPart;
|
var expectedPasswordPart = ExpectedPasswordPart;
|
||||||
if (pwd.Text == expectedPasswordPart)
|
if (pwd.Text == expectedPasswordPart)
|
||||||
{
|
{
|
||||||
Kp2aLog.Log("QuickUnlock successful!");
|
UnlockAndSyncAndClose();
|
||||||
App.Kp2a.UnlockDatabase();
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Kp2aLog.Log("QuickUnlock not successful!");
|
Kp2aLog.Log("QuickUnlock not successful!");
|
||||||
App.Kp2a.Lock(false);
|
App.Kp2a.Lock(false);
|
||||||
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
|
||||||
|
Finish();
|
||||||
}
|
}
|
||||||
Finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ExpectedPasswordPart
|
private void UnlockAndSyncAndClose()
|
||||||
|
{
|
||||||
|
App.Kp2a.UnlockDatabase();
|
||||||
|
|
||||||
|
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||||
|
.GetBoolean(GetString(Resource.String.SyncAfterQuickUnlock_key), false))
|
||||||
|
{
|
||||||
|
new SyncUtil(this).SynchronizeDatabase(Finish);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Finish();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ExpectedPasswordPart
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@@ -205,6 +205,8 @@
|
|||||||
<string name="PreloadDatabaseEnabled_key">PreloadDatabaseEnabled</string>
|
<string name="PreloadDatabaseEnabled_key">PreloadDatabaseEnabled</string>
|
||||||
<bool name="PreloadDatabaseEnabled_default">true</bool>
|
<bool name="PreloadDatabaseEnabled_default">true</bool>
|
||||||
|
|
||||||
|
<string name="SyncAfterQuickUnlock_key">SyncAfterQuickUnlock_key</string>
|
||||||
|
|
||||||
<string name="ClearPasswordOnLeave_key">ClearPasswordOnLeave</string>
|
<string name="ClearPasswordOnLeave_key">ClearPasswordOnLeave</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@@ -473,6 +473,9 @@
|
|||||||
<string name="PreloadDatabaseEnabled_title">Pre-load database file</string>
|
<string name="PreloadDatabaseEnabled_title">Pre-load database file</string>
|
||||||
<string name="PreloadDatabaseEnabled_summary">Start background loading or downloading of the database file during password entry.</string>
|
<string name="PreloadDatabaseEnabled_summary">Start background loading or downloading of the database file during password entry.</string>
|
||||||
|
|
||||||
|
<string name="SyncAfterQuickUnlock_title">Sync after QuickUnlock</string>
|
||||||
|
<string name="SyncAfterQuickUnlock_summary">Synchronize database with remote file after unlocking with QuickUnlock.</string>
|
||||||
|
|
||||||
<string name="AskOverwriteBinary">Do you want to overwrite the existing binary with the same name?</string>
|
<string name="AskOverwriteBinary">Do you want to overwrite the existing binary with the same name?</string>
|
||||||
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
|
<string name="AskOverwriteBinary_title">Overwrite existing binary?</string>
|
||||||
<string name="AskOverwriteBinary_yes">Overwrite</string>
|
<string name="AskOverwriteBinary_yes">Overwrite</string>
|
||||||
|
@@ -567,7 +567,15 @@
|
|||||||
android:defaultValue="@bool/PreloadDatabaseEnabled_default"
|
android:defaultValue="@bool/PreloadDatabaseEnabled_default"
|
||||||
android:title="@string/PreloadDatabaseEnabled_title"
|
android:title="@string/PreloadDatabaseEnabled_title"
|
||||||
android:key="@string/PreloadDatabaseEnabled_key" />
|
android:key="@string/PreloadDatabaseEnabled_key" />
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
|
android:enabled="true"
|
||||||
|
android:persistent="true"
|
||||||
|
android:summary="@string/SyncAfterQuickUnlock_summary"
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:title="@string/SyncAfterQuickUnlock_title"
|
||||||
|
android:key="@string/SyncAfterQuickUnlock_key" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
android:key="@string/TanExpiresOnUse_key"
|
android:key="@string/TanExpiresOnUse_key"
|
||||||
android:title="@string/TanExpiresOnUse_title"
|
android:title="@string/TanExpiresOnUse_title"
|
||||||
android:summary="@string/TanExpiresOnUse_summary"
|
android:summary="@string/TanExpiresOnUse_summary"
|
||||||
|
99
src/keepass2android/SyncUtil.cs
Normal file
99
src/keepass2android/SyncUtil.cs
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
using System;
|
||||||
|
using Android.App;
|
||||||
|
using Android.Widget;
|
||||||
|
using keepass2android.Io;
|
||||||
|
using KeePassLib.Serialization;
|
||||||
|
|
||||||
|
namespace keepass2android
|
||||||
|
{
|
||||||
|
public class SyncUtil
|
||||||
|
{
|
||||||
|
private Activity _activity;
|
||||||
|
|
||||||
|
public SyncUtil(Activity activity)
|
||||||
|
{
|
||||||
|
_activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SyncOtpAuxFile : RunnableOnFinish
|
||||||
|
{
|
||||||
|
private readonly IOConnectionInfo _ioc;
|
||||||
|
|
||||||
|
public SyncOtpAuxFile(Activity activity, IOConnectionInfo ioc)
|
||||||
|
: base(activity, null)
|
||||||
|
{
|
||||||
|
_ioc = ioc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
StatusLogger.UpdateMessage(UiStringKey.SynchronizingOtpAuxFile);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//simply open the file. The file storage does a complete sync.
|
||||||
|
using (App.Kp2a.GetOtpAuxFileStorage(_ioc).OpenFileForRead(_ioc))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Finish(true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
Finish(false, e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SynchronizeDatabase(Action runAfterSuccess)
|
||||||
|
{
|
||||||
|
var filestorage = App.Kp2a.GetFileStorage(App.Kp2a.CurrentDb.Ioc);
|
||||||
|
RunnableOnFinish task;
|
||||||
|
OnFinish onFinish = new ActionOnFinish(_activity, (success, message, activity) =>
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(message))
|
||||||
|
Toast.MakeText(activity, message, ToastLength.Long).Show();
|
||||||
|
|
||||||
|
// Tell the adapter to refresh it's list
|
||||||
|
BaseAdapter adapter = (activity as GroupBaseActivity)?.ListAdapter;
|
||||||
|
adapter?.NotifyDataSetChanged();
|
||||||
|
|
||||||
|
if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null)
|
||||||
|
{
|
||||||
|
var task2 = new SyncOtpAuxFile(_activity, App.Kp2a.CurrentDb.OtpAuxFileIoc);
|
||||||
|
task2.OnFinishToRun = new ActionOnFinish(_activity, (b, s, activeActivity) =>
|
||||||
|
{
|
||||||
|
runAfterSuccess();
|
||||||
|
});
|
||||||
|
new ProgressTask(App.Kp2a, activity, task2).Run(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runAfterSuccess();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (filestorage is CachingFileStorage)
|
||||||
|
{
|
||||||
|
|
||||||
|
task = new SynchronizeCachedDatabase(_activity, App.Kp2a, onFinish);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
task = new CheckDatabaseForChanges(_activity, App.Kp2a, onFinish);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var progressTask = new ProgressTask(App.Kp2a, _activity, task);
|
||||||
|
progressTask.Run();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -460,14 +460,14 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AskForReload(activity);
|
AskForReload(activity, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void AskForReload(Activity activity)
|
private void AskForReload(Activity activity, Action<bool> actionOnResult)
|
||||||
{
|
{
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
|
builder.SetTitle(activity.GetString(Resource.String.AskReloadFile_title));
|
||||||
@@ -480,16 +480,27 @@ namespace keepass2android
|
|||||||
CurrentDb.ReloadRequested = true;
|
CurrentDb.ReloadRequested = true;
|
||||||
activity.SetResult(KeePass.ExitReloadDb);
|
activity.SetResult(KeePass.ExitReloadDb);
|
||||||
activity.Finish();
|
activity.Finish();
|
||||||
|
if (actionOnResult != null)
|
||||||
|
actionOnResult(true);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), (dlgSender, dlgEvt) =>
|
builder.SetNegativeButton(activity.GetString(Android.Resource.String.No), (dlgSender, dlgEvt) =>
|
||||||
{
|
{
|
||||||
|
if (actionOnResult != null)
|
||||||
|
actionOnResult(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Dialog dialog = builder.Create();
|
Dialog dialog = builder.Create();
|
||||||
|
|
||||||
|
dialog.SetOnDismissListener(new Util.DismissListener(() =>
|
||||||
|
{
|
||||||
|
if (actionOnResult != null)
|
||||||
|
actionOnResult(false);
|
||||||
|
}));
|
||||||
|
|
||||||
dialog.Show();
|
dialog.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,12 +744,12 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TriggerReload(Context ctx)
|
public void TriggerReload(Context ctx, Action<bool> actionOnResult)
|
||||||
{
|
{
|
||||||
Handler handler = new Handler(Looper.MainLooper);
|
Handler handler = new Handler(Looper.MainLooper);
|
||||||
handler.Post(() =>
|
handler.Post(() =>
|
||||||
{
|
{
|
||||||
AskForReload((Activity) ctx);
|
AskForReload((Activity) ctx, actionOnResult);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -207,6 +207,7 @@
|
|||||||
<Compile Include="settings\ExportKeyfileActivity.cs" />
|
<Compile Include="settings\ExportKeyfileActivity.cs" />
|
||||||
<Compile Include="settings\IconSetPreference.cs" />
|
<Compile Include="settings\IconSetPreference.cs" />
|
||||||
<Compile Include="SwitchImeActivity.cs" />
|
<Compile Include="SwitchImeActivity.cs" />
|
||||||
|
<Compile Include="SyncUtil.cs" />
|
||||||
<Compile Include="timeout\TimeoutHelper.cs" />
|
<Compile Include="timeout\TimeoutHelper.cs" />
|
||||||
<Compile Include="GroupActivity.cs" />
|
<Compile Include="GroupActivity.cs" />
|
||||||
<Compile Include="GroupBaseActivity.cs" />
|
<Compile Include="GroupBaseActivity.cs" />
|
||||||
|
Reference in New Issue
Block a user