LoadDb and SaveDb respect the SyncInBackground preference
This commit is contained in:
@@ -141,5 +141,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
bool SyncInBackgroundPreference { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -186,8 +186,11 @@ namespace keepass2android.Io
|
|||||||
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
|
Kp2aLog.Log("couldn't open from remote " + ioc.Path);
|
||||||
#endif
|
#endif
|
||||||
Kp2aLog.Log(ex.ToString());
|
Kp2aLog.Log(ex.ToString());
|
||||||
|
if (TriggerWarningWhenFallingBackToCache)
|
||||||
|
{
|
||||||
|
_cacheSupervisor.CouldntOpenFromRemote(ioc, ex);
|
||||||
|
}
|
||||||
|
|
||||||
_cacheSupervisor.CouldntOpenFromRemote(ioc, ex);
|
|
||||||
return File.OpenRead(cachedFilePath);
|
return File.OpenRead(cachedFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,7 +330,10 @@ namespace keepass2android.Io
|
|||||||
Kp2aLog.Log("couldn't save to remote " + ioc.Path);
|
Kp2aLog.Log("couldn't save to remote " + ioc.Path);
|
||||||
Kp2aLog.Log(e.ToString());
|
Kp2aLog.Log(e.ToString());
|
||||||
//notify the supervisor so it might display a warning or schedule a retry
|
//notify the supervisor so it might display a warning or schedule a retry
|
||||||
_cacheSupervisor.CouldntSaveToRemote(ioc, e);
|
if (TriggerWarningWhenFallingBackToCache)
|
||||||
|
{
|
||||||
|
_cacheSupervisor.CouldntSaveToRemote(ioc, e); }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,7 +638,9 @@ namespace keepass2android.Io
|
|||||||
set { _cachedStorage.IsOffline = value; }
|
set { _cachedStorage.IsOffline = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnRequestPermissionsResult(IFileStorageSetupActivity fileStorageSetupActivity, int requestCode,
|
public bool TriggerWarningWhenFallingBackToCache { get; set; }
|
||||||
|
|
||||||
|
public void OnRequestPermissionsResult(IFileStorageSetupActivity fileStorageSetupActivity, int requestCode,
|
||||||
string[] permissions, Permission[] grantResults)
|
string[] permissions, Permission[] grantResults)
|
||||||
{
|
{
|
||||||
_cachedStorage.OnRequestPermissionsResult(fileStorageSetupActivity, requestCode, permissions, grantResults);
|
_cachedStorage.OnRequestPermissionsResult(fileStorageSetupActivity, requestCode, permissions, grantResults);
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ namespace keepass2android.Io
|
|||||||
public interface IOfflineSwitchable
|
public interface IOfflineSwitchable
|
||||||
{
|
{
|
||||||
bool IsOffline { get; set; }
|
bool IsOffline { get; set; }
|
||||||
}
|
bool TriggerWarningWhenFallingBackToCache { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encapsulates another IFileStorage. Allows to switch to offline mode by throwing
|
/// Encapsulates another IFileStorage. Allows to switch to offline mode by throwing
|
||||||
@@ -21,8 +22,9 @@ namespace keepass2android.Io
|
|||||||
{
|
{
|
||||||
private readonly IFileStorage _baseStorage;
|
private readonly IFileStorage _baseStorage;
|
||||||
public bool IsOffline { get; set; }
|
public bool IsOffline { get; set; }
|
||||||
|
public bool TriggerWarningWhenFallingBackToCache { get; set; }
|
||||||
|
|
||||||
public OfflineSwitchableFileStorage(IFileStorage baseStorage)
|
public OfflineSwitchableFileStorage(IFileStorage baseStorage)
|
||||||
{
|
{
|
||||||
_baseStorage = baseStorage;
|
_baseStorage = baseStorage;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,9 +194,9 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SaveData() {
|
public void SaveData(IFileStorage fileStorage) {
|
||||||
|
|
||||||
using (IWriteTransaction trans = _app.GetFileStorage(Ioc).OpenWriteTransaction(Ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
|
using (IWriteTransaction trans = fileStorage.OpenWriteTransaction(Ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions)))
|
||||||
{
|
{
|
||||||
DatabaseFormat.Save(KpDatabase, trans.OpenFile());
|
DatabaseFormat.Save(KpDatabase, trans.OpenFile());
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
|
using Android.OS;
|
||||||
using KeePass.Util;
|
using KeePass.Util;
|
||||||
using keepass2android.database.edit;
|
using keepass2android.database.edit;
|
||||||
|
using keepass2android.Io;
|
||||||
using KeePassLib;
|
using KeePassLib;
|
||||||
using KeePassLib.Keys;
|
using KeePassLib.Keys;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
@@ -47,8 +49,6 @@ namespace keepass2android
|
|||||||
_keyfileOrProvider = keyfileOrProvider;
|
_keyfileOrProvider = keyfileOrProvider;
|
||||||
_updateLastUsageTimestamp = updateLastUsageTimestamp;
|
_updateLastUsageTimestamp = updateLastUsageTimestamp;
|
||||||
_makeCurrent = makeCurrent;
|
_makeCurrent = makeCurrent;
|
||||||
|
|
||||||
|
|
||||||
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
_rememberKeyfile = app.GetBooleanPreference(PreferenceKey.remember_keyfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,16 +65,31 @@ namespace keepass2android
|
|||||||
//make sure the file data is stored in the recent files list even if loading fails
|
//make sure the file data is stored in the recent files list even if loading fails
|
||||||
SaveFileData(_ioc, _keyfileOrProvider);
|
SaveFileData(_ioc, _keyfileOrProvider);
|
||||||
|
|
||||||
|
var fileStorage = _app.GetFileStorage(_ioc);
|
||||||
|
|
||||||
|
bool requiresSubsequentSync = false;
|
||||||
|
|
||||||
|
|
||||||
StatusLogger.UpdateMessage(UiStringKey.loading_database);
|
StatusLogger.UpdateMessage(UiStringKey.loading_database);
|
||||||
//get the stream data into a single stream variable (databaseStream) regardless whether its preloaded or not:
|
//get the stream data into a single stream variable (databaseStream) regardless whether its preloaded or not:
|
||||||
MemoryStream preloadedMemoryStream = _databaseData == null ? null : _databaseData.Result;
|
MemoryStream preloadedMemoryStream = _databaseData == null ? null : _databaseData.Result;
|
||||||
MemoryStream databaseStream;
|
MemoryStream databaseStream;
|
||||||
if (preloadedMemoryStream != null)
|
if (preloadedMemoryStream != null)
|
||||||
databaseStream = preloadedMemoryStream;
|
{
|
||||||
else
|
//note: if the stream has been loaded already, we don't need to trigger another sync later on
|
||||||
|
databaseStream = preloadedMemoryStream;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
using (Stream s = _app.GetFileStorage(_ioc).OpenFileForRead(_ioc))
|
if (_app.SyncInBackgroundPreference && fileStorage is IOfflineSwitchable offlineSwitchable)
|
||||||
|
{
|
||||||
|
offlineSwitchable.IsOffline = true;
|
||||||
|
//no warning. We'll trigger a sync later.
|
||||||
|
offlineSwitchable.TriggerWarningWhenFallingBackToCache = false;
|
||||||
|
requiresSubsequentSync = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
using (Stream s = fileStorage.OpenFileForRead(_ioc))
|
||||||
{
|
{
|
||||||
databaseStream = new MemoryStream();
|
databaseStream = new MemoryStream();
|
||||||
s.CopyTo(databaseStream);
|
s.CopyTo(databaseStream);
|
||||||
@@ -83,8 +98,8 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
|
//ok, try to load the database. Let's start with Kdbx format and retry later if that is the wrong guess:
|
||||||
_format = new KdbxDatabaseFormat(KdbxDatabaseFormat.GetFormatToUse(_app.GetFileStorage(_ioc).GetFileExtension(_ioc)));
|
_format = new KdbxDatabaseFormat(KdbxDatabaseFormat.GetFormatToUse(fileStorage.GetFileExtension(_ioc)));
|
||||||
TryLoad(databaseStream);
|
TryLoad(databaseStream, requiresSubsequentSync);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -136,7 +151,7 @@ namespace keepass2android
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Exception Exception { get; set; }
|
public Exception Exception { get; set; }
|
||||||
|
|
||||||
Database TryLoad(MemoryStream databaseStream)
|
Database TryLoad(MemoryStream databaseStream, bool requiresSubsequentSync)
|
||||||
{
|
{
|
||||||
//create a copy of the stream so we can try again if we get an exception which indicates we should change parameters
|
//create a copy of the stream so we can try again if we get an exception which indicates we should change parameters
|
||||||
//This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors.
|
//This is not optimal in terms of (short-time) memory usage but is hard to avoid because the Keepass library closes streams also in case of errors.
|
||||||
@@ -150,7 +165,20 @@ namespace keepass2android
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format, _makeCurrent);
|
Database newDb = _app.LoadDatabase(_ioc, workingCopy, _compositeKey, StatusLogger, _format, _makeCurrent);
|
||||||
Kp2aLog.Log("LoadDB OK");
|
Kp2aLog.Log("LoadDB OK");
|
||||||
|
|
||||||
|
if (requiresSubsequentSync)
|
||||||
|
{
|
||||||
|
var syncTask = new SynchronizeCachedDatabase(ActiveActivity, _app, new ActionOnOperationFinished(ActiveActivity,
|
||||||
|
(success, message, activeActivity) =>
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(message))
|
||||||
|
_app.ShowMessage(activeActivity, message, success ? MessageSeverity.Info : MessageSeverity.Error);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
BackgroundOperationRunner.Instance.Run(ActiveActivity, _app, syncTask);
|
||||||
|
}
|
||||||
|
|
||||||
Finish(true, _format.SuccessMessage);
|
Finish(true, _format.SuccessMessage);
|
||||||
return newDb;
|
return newDb;
|
||||||
@@ -158,7 +186,7 @@ namespace keepass2android
|
|||||||
catch (OldFormatException)
|
catch (OldFormatException)
|
||||||
{
|
{
|
||||||
_format = new KdbDatabaseFormat(_app);
|
_format = new KdbDatabaseFormat(_app);
|
||||||
return TryLoad(databaseStream);
|
return TryLoad(databaseStream, requiresSubsequentSync);
|
||||||
}
|
}
|
||||||
catch (InvalidCompositeKeyException)
|
catch (InvalidCompositeKeyException)
|
||||||
{
|
{
|
||||||
@@ -170,7 +198,7 @@ namespace keepass2android
|
|||||||
//retry without password:
|
//retry without password:
|
||||||
_compositeKey.RemoveUserKey(passwordKey);
|
_compositeKey.RemoveUserKey(passwordKey);
|
||||||
//retry:
|
//retry:
|
||||||
return TryLoad(databaseStream);
|
return TryLoad(databaseStream, requiresSubsequentSync);
|
||||||
}
|
}
|
||||||
else throw;
|
else throw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace keepass2android
|
|||||||
private readonly IKp2aApp _app;
|
private readonly IKp2aApp _app;
|
||||||
private readonly Database _db;
|
private readonly Database _db;
|
||||||
private readonly bool _dontSave;
|
private readonly bool _dontSave;
|
||||||
|
private bool requiresSubsequentSync = false; //if true, we need to sync the file after saving.
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// stream for reading the data from the original file. If this is set to a non-null value, we know we need to sync
|
/// stream for reading the data from the original file. If this is set to a non-null value, we know we need to sync
|
||||||
@@ -108,13 +109,23 @@ namespace keepass2android
|
|||||||
IOConnectionInfo ioc = _db.Ioc;
|
IOConnectionInfo ioc = _db.Ioc;
|
||||||
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
||||||
|
|
||||||
if (_streamForOrigFile == null)
|
if (_app.SyncInBackgroundPreference && fileStorage is IOfflineSwitchable offlineSwitchable)
|
||||||
|
{
|
||||||
|
offlineSwitchable.IsOffline = true;
|
||||||
|
//no warning. We'll trigger a sync later.
|
||||||
|
offlineSwitchable.TriggerWarningWhenFallingBackToCache = false;
|
||||||
|
requiresSubsequentSync = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (_streamForOrigFile == null)
|
||||||
{
|
{
|
||||||
if ((!_app.GetBooleanPreference(PreferenceKey.CheckForFileChangesOnSave))
|
if ((!_app.GetBooleanPreference(PreferenceKey.CheckForFileChangesOnSave))
|
||||||
|| (_db.KpDatabase.HashOfFileOnDisk == null)) //first time saving
|
|| (_db.KpDatabase.HashOfFileOnDisk == null)) //first time saving
|
||||||
{
|
{
|
||||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||||
Finish(true);
|
FinishWithSuccess();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,9 +134,9 @@ namespace keepass2android
|
|||||||
bool hasStreamForOrigFile = (_streamForOrigFile != null);
|
bool hasStreamForOrigFile = (_streamForOrigFile != null);
|
||||||
bool hasChangeFast = hasStreamForOrigFile ||
|
bool hasChangeFast = hasStreamForOrigFile ||
|
||||||
fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion); //first try to use the fast change detection;
|
fileStorage.CheckForFileChangeFast(ioc, _db.LastFileVersion); //first try to use the fast change detection;
|
||||||
bool hasHashChanged = hasChangeFast ||
|
bool hasHashChanged = !requiresSubsequentSync && (hasChangeFast ||
|
||||||
(FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) ==
|
(FileHashChanged(ioc, _db.KpDatabase.HashOfFileOnDisk) ==
|
||||||
FileHashChange.Changed); //if that fails, hash the file and compare:
|
FileHashChange.Changed)); //if that fails, hash the file and compare:
|
||||||
|
|
||||||
if (hasHashChanged)
|
if (hasHashChanged)
|
||||||
{
|
{
|
||||||
@@ -158,7 +169,7 @@ namespace keepass2android
|
|||||||
RunInWorkerThread(() =>
|
RunInWorkerThread(() =>
|
||||||
{
|
{
|
||||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||||
Finish(true);
|
FinishWithSuccess();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
//cancel
|
//cancel
|
||||||
@@ -174,7 +185,7 @@ namespace keepass2android
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||||
Finish(true);
|
FinishWithSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -194,11 +205,28 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Finish(true);
|
FinishWithSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FinishWithSuccess()
|
||||||
|
{
|
||||||
|
if (requiresSubsequentSync)
|
||||||
|
{
|
||||||
|
var syncTask = new SynchronizeCachedDatabase(ActiveActivity, _app, new ActionOnOperationFinished(ActiveActivity,
|
||||||
|
(success, message, activeActivity) =>
|
||||||
|
{
|
||||||
|
if (!System.String.IsNullOrEmpty(message))
|
||||||
|
_app.ShowMessage(activeActivity, message, success ? MessageSeverity.Info : MessageSeverity.Error);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
BackgroundOperationRunner.Instance.Run(ActiveActivity, _app, syncTask);
|
||||||
|
}
|
||||||
|
Finish(true);
|
||||||
|
}
|
||||||
|
|
||||||
private void MergeAndFinish(IFileStorage fileStorage, IOConnectionInfo ioc)
|
private void MergeAndFinish(IFileStorage fileStorage, IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
//note: when synced, the file might be downloaded once again from the server. Caching the data
|
//note: when synced, the file might be downloaded once again from the server. Caching the data
|
||||||
@@ -207,7 +235,7 @@ namespace keepass2android
|
|||||||
MergeIn(fileStorage, ioc);
|
MergeIn(fileStorage, ioc);
|
||||||
PerformSaveWithoutCheck(fileStorage, ioc);
|
PerformSaveWithoutCheck(fileStorage, ioc);
|
||||||
_db.UpdateGlobals();
|
_db.UpdateGlobals();
|
||||||
Finish(true);
|
FinishWithSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RunInWorkerThread(Action runHandler)
|
private void RunInWorkerThread(Action runHandler)
|
||||||
@@ -282,7 +310,7 @@ namespace keepass2android
|
|||||||
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
|
private void PerformSaveWithoutCheck(IFileStorage fileStorage, IOConnectionInfo ioc)
|
||||||
{
|
{
|
||||||
StatusLogger.UpdateSubMessage("");
|
StatusLogger.UpdateSubMessage("");
|
||||||
_db.SaveData();
|
_db.SaveData(fileStorage);
|
||||||
_db.LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
_db.LastFileVersion = fileStorage.GetCurrentFileVersionFast(ioc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1753,17 +1753,10 @@ namespace keepass2android
|
|||||||
cbOfflineMode.Checked =
|
cbOfflineMode.Checked =
|
||||||
App.Kp2a
|
App.Kp2a
|
||||||
.OfflineModePreference; //this won't overwrite new user settings because every change is directly saved in settings
|
.OfflineModePreference; //this won't overwrite new user settings because every change is directly saved in settings
|
||||||
LinearLayout offlineModeContainer = FindViewById<LinearLayout>(Resource.Id.work_offline_container);
|
|
||||||
var cachingFileStorage = App.Kp2a.GetFileStorage(_ioConnection) as CachingFileStorage;
|
CheckBox cbSyncInBackground = (CheckBox)FindViewById(Resource.Id.sync_in_background)!;
|
||||||
if ((cachingFileStorage != null) && cachingFileStorage.IsCached(_ioConnection))
|
cbSyncInBackground.Checked = App.Kp2a.SyncInBackgroundPreference;
|
||||||
{
|
UpdateInternalCacheCheckboxesVisibility();
|
||||||
offlineModeContainer.Visibility = ViewStates.Visible;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
offlineModeContainer.Visibility = ViewStates.Gone;
|
|
||||||
App.Kp2a.OfflineMode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -2040,9 +2033,37 @@ namespace keepass2android
|
|||||||
App.Kp2a.OfflineModePreference = App.Kp2a.OfflineMode = args.IsChecked;
|
App.Kp2a.OfflineModePreference = App.Kp2a.OfflineMode = args.IsChecked;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
CheckBox cbSyncInBackground = (CheckBox)FindViewById(Resource.Id.sync_in_background);
|
||||||
|
cbSyncInBackground.CheckedChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
App.Kp2a.SyncInBackgroundPreference = args.IsChecked;
|
||||||
|
UpdateInternalCacheCheckboxesVisibility();
|
||||||
|
|
||||||
private String LoadKeyProviderStringForIoc(String filename) {
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateInternalCacheCheckboxesVisibility()
|
||||||
|
{
|
||||||
|
|
||||||
|
LinearLayout syncInBackgroundContainer = FindViewById<LinearLayout>(Resource.Id.sync_in_background_container)!;
|
||||||
|
|
||||||
|
LinearLayout offlineModeContainer = FindViewById<LinearLayout>(Resource.Id.work_offline_container)!;
|
||||||
|
var cachingFileStorage = App.Kp2a.GetFileStorage(_ioConnection) as CachingFileStorage;
|
||||||
|
if ((cachingFileStorage != null) && cachingFileStorage.IsCached(_ioConnection))
|
||||||
|
{
|
||||||
|
syncInBackgroundContainer.Visibility = ViewStates.Visible;
|
||||||
|
offlineModeContainer.Visibility =
|
||||||
|
App.Kp2a.SyncInBackgroundPreference ? ViewStates.Gone : ViewStates.Visible;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syncInBackgroundContainer.Visibility = offlineModeContainer.Visibility = ViewStates.Gone;
|
||||||
|
App.Kp2a.OfflineMode = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String LoadKeyProviderStringForIoc(String filename) {
|
||||||
if ( _rememberKeyfile ) {
|
if ( _rememberKeyfile ) {
|
||||||
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(filename);
|
string keyfile = App.Kp2a.FileDbHelper.GetKeyFileForFile(filename);
|
||||||
if (String.IsNullOrEmpty(keyfile))
|
if (String.IsNullOrEmpty(keyfile))
|
||||||
|
|||||||
@@ -318,6 +318,30 @@
|
|||||||
android:text="@string/help_quickunlock"
|
android:text="@string/help_quickunlock"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/sync_in_background_container"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/sync_in_background"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/SyncOfflineCacheInBackground_title" />
|
||||||
|
<keepass2android.views.Kp2aShortHelpView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/TextAppearance_Help_Dense"
|
||||||
|
|
||||||
|
app:help_text="@string/SyncOfflineCacheInBackground_summary"
|
||||||
|
app:title_text="@string/SyncOfflineCacheInBackground_title"
|
||||||
|
android:text="@string/SyncOfflineCacheInBackground_summary"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/work_offline_container"
|
android:id="@+id/work_offline_container"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
@@ -328,7 +352,7 @@
|
|||||||
android:id="@+id/work_offline"
|
android:id="@+id/work_offline"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:text="@string/UseOfflineMode" />
|
android:text="@string/UseOfflineMode" />
|
||||||
<keepass2android.views.Kp2aShortHelpView
|
<keepass2android.views.Kp2aShortHelpView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -341,6 +365,7 @@
|
|||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/kill_app"
|
android:id="@+id/kill_app"
|
||||||
android:text="@string/kill_app_label"
|
android:text="@string/kill_app_label"
|
||||||
|
|||||||
@@ -56,12 +56,16 @@ namespace keepass2android
|
|||||||
OperationWithFinishHandler task;
|
OperationWithFinishHandler task;
|
||||||
OnOperationFinishedHandler onOperationFinishedHandler = new ActionOnOperationFinished(_activity, (success, message, activity) =>
|
OnOperationFinishedHandler onOperationFinishedHandler = new ActionOnOperationFinished(_activity, (success, message, activity) =>
|
||||||
{
|
{
|
||||||
if (!String.IsNullOrEmpty(message))
|
new Handler(Looper.MainLooper).Post(() =>
|
||||||
App.Kp2a.ShowMessage(activity, message, success ? MessageSeverity.Info : MessageSeverity.Error);
|
{
|
||||||
|
if (!String.IsNullOrEmpty(message))
|
||||||
|
App.Kp2a.ShowMessage(activity, message, success ? MessageSeverity.Info : MessageSeverity.Error);
|
||||||
|
|
||||||
// Tell the adapter to refresh it's list
|
// Tell the adapter to refresh it's list
|
||||||
BaseAdapter adapter = (activity as GroupBaseActivity)?.ListAdapter;
|
BaseAdapter adapter = (activity as GroupBaseActivity)?.ListAdapter;
|
||||||
new Handler(Looper.MainLooper).Post(() => adapter?.NotifyDataSetChanged());
|
|
||||||
|
adapter?.NotifyDataSetChanged();
|
||||||
|
});
|
||||||
|
|
||||||
if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null)
|
if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ namespace keepass2android.Utils
|
|||||||
{
|
{
|
||||||
public void ShowMessage(Message message)
|
public void ShowMessage(Message message)
|
||||||
{
|
{
|
||||||
Toast.MakeText(App.Context, message.Text, ToastLength.Long).Show();
|
new Handler(Looper.MainLooper).Post(() =>
|
||||||
|
{
|
||||||
|
Toast.MakeText(App.Context, message.Text, ToastLength.Long).Show();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Message> PendingMessages => new();
|
public List<Message> PendingMessages => new();
|
||||||
|
|||||||
@@ -798,9 +798,14 @@ namespace keepass2android
|
|||||||
fileStorage = innerFileStorage;
|
fileStorage = innerFileStorage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fileStorage is IOfflineSwitchable)
|
if (fileStorage is IOfflineSwitchable switchable)
|
||||||
{
|
{
|
||||||
((IOfflineSwitchable)fileStorage).IsOffline = App.Kp2a.OfflineMode;
|
switchable.IsOffline = App.Kp2a.OfflineMode;
|
||||||
|
if (switchable.IsOffline)
|
||||||
|
{
|
||||||
|
//users of the file storage can set this to false, but the default is to show a warning:
|
||||||
|
switchable.TriggerWarningWhenFallingBackToCache = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return fileStorage;
|
return fileStorage;
|
||||||
}
|
}
|
||||||
@@ -1151,10 +1156,28 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// true if the app is used in offline mode
|
public bool SyncInBackgroundPreference
|
||||||
/// </summary>
|
{
|
||||||
public bool OfflineMode
|
get
|
||||||
|
{
|
||||||
|
var prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
|
||||||
|
return prefs.GetBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.SyncOfflineCacheInBackground_key), false);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(LocaleManager.LocalizedAppContext);
|
||||||
|
ISharedPreferencesEditor edit = prefs.Edit();
|
||||||
|
edit.PutBoolean(LocaleManager.LocalizedAppContext.GetString(Resource.String.SyncOfflineCacheInBackground_key), value);
|
||||||
|
edit.Commit();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// true if the app is used in offline mode
|
||||||
|
/// </summary>
|
||||||
|
public bool OfflineMode
|
||||||
{
|
{
|
||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user