134 lines
4.1 KiB
C#
134 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Android.App;
|
|
using Android.Content;
|
|
using KeePassLib.Serialization;
|
|
using keepass2android.Io;
|
|
using KeePass.Util;
|
|
|
|
namespace keepass2android
|
|
{
|
|
public class SynchronizeCachedDatabase: OperationWithFinishHandler
|
|
{
|
|
private readonly Context _context;
|
|
private readonly IKp2aApp _app;
|
|
private SaveDb _saveDb;
|
|
|
|
public SynchronizeCachedDatabase(IKp2aApp app, OnOperationFinishedHandler operationFinishedHandler)
|
|
: base(app, operationFinishedHandler)
|
|
{
|
|
_app = app;
|
|
}
|
|
|
|
public override void Run()
|
|
{
|
|
try
|
|
{
|
|
IOConnectionInfo ioc = _app.CurrentDb.Ioc;
|
|
IFileStorage fileStorage = _app.GetFileStorage(ioc);
|
|
if (!(fileStorage is CachingFileStorage))
|
|
{
|
|
throw new Exception("Cannot sync a non-cached database!");
|
|
}
|
|
StatusLogger.UpdateMessage(UiStringKey.SynchronizingCachedDatabase);
|
|
CachingFileStorage cachingFileStorage = (CachingFileStorage) fileStorage;
|
|
|
|
//download file from remote location and calculate hash:
|
|
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.DownloadingRemoteFile));
|
|
string hash;
|
|
|
|
//TODO remove
|
|
Thread.Sleep(5000);
|
|
|
|
MemoryStream remoteData;
|
|
try
|
|
{
|
|
remoteData = cachingFileStorage.GetRemoteDataAndHash(ioc, out hash);
|
|
Kp2aLog.Log("Checking for file change. Current hash = " + hash);
|
|
}
|
|
catch (FileNotFoundException)
|
|
{
|
|
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.RestoringRemoteFile));
|
|
cachingFileStorage.UpdateRemoteFile(ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions));
|
|
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
|
|
Kp2aLog.Log("Checking for file change: file not found");
|
|
return;
|
|
}
|
|
|
|
//check if remote file was modified:
|
|
var baseVersionHash = cachingFileStorage.GetBaseVersionHash(ioc);
|
|
Kp2aLog.Log("Checking for file change. baseVersionHash = " + baseVersionHash);
|
|
if (baseVersionHash != hash ||
|
|
true//TODO remove
|
|
)
|
|
{
|
|
//remote file is modified
|
|
if (cachingFileStorage.HasLocalChanges(ioc)
|
|
|| true //TODO remove
|
|
)
|
|
{
|
|
//conflict! need to merge
|
|
_saveDb = new SaveDb(_app, new ActionOnOperationFinished(_app, (success, result, activity) =>
|
|
{
|
|
if (!success)
|
|
{
|
|
Finish(false, result);
|
|
}
|
|
else
|
|
{
|
|
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
|
|
}
|
|
_saveDb = null;
|
|
}), _app.CurrentDb, false, remoteData);
|
|
_saveDb.SetStatusLogger(StatusLogger);
|
|
_saveDb.DoNotSetStatusLoggerMessage = true; //Keep "sync db" as main message
|
|
_saveDb.SyncInBackground = false;
|
|
_saveDb.Run();
|
|
|
|
_app.CurrentDb.UpdateGlobals();
|
|
|
|
_app.MarkAllGroupsAsDirty();
|
|
}
|
|
else
|
|
{
|
|
//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.)
|
|
_app.TriggerReload(_context, (bool result) => Finish(result));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//remote file is unmodified
|
|
if (cachingFileStorage.HasLocalChanges(ioc))
|
|
{
|
|
//but we have local changes -> upload:
|
|
StatusLogger.UpdateSubMessage(_app.GetResourceString(UiStringKey.UploadingFile));
|
|
cachingFileStorage.UpdateRemoteFile(ioc, _app.GetBooleanPreference(PreferenceKey.UseFileTransactions));
|
|
StatusLogger.UpdateSubMessage("");
|
|
Finish(true, _app.GetResourceString(UiStringKey.SynchronizedDatabaseSuccessfully));
|
|
}
|
|
else
|
|
{
|
|
//files are in sync: just set the result
|
|
Finish(true, _app.GetResourceString(UiStringKey.FilesInSync));
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Kp2aLog.LogUnexpectedError(e);
|
|
Finish(false, ExceptionUtil.GetErrorMessage(e));
|
|
}
|
|
|
|
}
|
|
|
|
public void JoinWorkerThread()
|
|
{
|
|
if (_saveDb != null)
|
|
_saveDb.JoinWorkerThread();
|
|
}
|
|
}
|
|
}
|