change blocking operations to use BackgroundSyncService also. Introduce pending actions for context instances.
This commit is contained in:
@@ -32,46 +32,59 @@ namespace keepass2android
|
|||||||
//for handling Activity recreation situations, we need access to the currently active task. It must hold that there is no more than one active task.
|
//for handling Activity recreation situations, we need access to the currently active task. It must hold that there is no more than one active task.
|
||||||
private static BlockingOperationRunner _currentTask = null;
|
private static BlockingOperationRunner _currentTask = null;
|
||||||
|
|
||||||
public static void SetNewActiveActivity(Activity activeActivity)
|
public static void SetNewActiveContext(Context activeContext)
|
||||||
{
|
{
|
||||||
if (_currentTask != null)
|
if (_currentTask != null)
|
||||||
{
|
{
|
||||||
_currentTask.ActiveActivity = activeActivity;
|
_currentTask.ActiveContext = activeContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void RemoveActiveActivity(Activity activity)
|
public static void RemoveActiveContext(Context context)
|
||||||
{
|
{
|
||||||
if ((_currentTask != null) && (_currentTask._activeActivity == activity))
|
if ((_currentTask != null) && (_currentTask._activeContext == context))
|
||||||
_currentTask.ActiveActivity = null;
|
_currentTask.ActiveContext = null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context ActiveActivity
|
public Context ActiveContext
|
||||||
{
|
{
|
||||||
get { return _activeActivity; }
|
get { return _activeContext; }
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
_activeActivity = value;
|
_activeContext = value;
|
||||||
|
|
||||||
if (_activeActivity != null)
|
if (_activeContext is Activity)
|
||||||
{
|
{
|
||||||
SetupProgressDialog(_app);
|
SetupProgressDialog(_app);
|
||||||
_progressDialog.Show();
|
_progressDialog.Show();
|
||||||
}
|
}
|
||||||
}
|
else if (_activeContext is Service and IProgressUiProvider progressUiProvider)
|
||||||
|
{
|
||||||
|
_statusLogger?.SetNewProgressUi(progressUiProvider.ProgressUi);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool HasActiveTask
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _currentTask != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private readonly Handler _handler;
|
private readonly Handler _handler;
|
||||||
private readonly OperationWithFinishHandler _task;
|
private readonly OperationWithFinishHandler _task;
|
||||||
private IProgressDialog _progressDialog;
|
private IProgressDialog _progressDialog;
|
||||||
private readonly IKp2aApp _app;
|
private readonly IKp2aApp _app;
|
||||||
private Java.Lang.Thread _thread;
|
private Java.Lang.Thread _thread;
|
||||||
private Context _activeActivity;
|
private Context _activeContext;
|
||||||
private ProgressDialogStatusLogger _progressDialogStatusLogger;
|
private ProgressUiAsStatusLoggerAdapter _statusLogger;
|
||||||
|
|
||||||
public BlockingOperationRunner(IKp2aApp app, OperationWithFinishHandler task)
|
public BlockingOperationRunner(IKp2aApp app, OperationWithFinishHandler task)
|
||||||
{
|
{
|
||||||
_activeActivity = app.ActiveContext;
|
_activeContext = app.ActiveContext;
|
||||||
_task = task;
|
_task = task;
|
||||||
_handler = app.UiThreadHandler;
|
_handler = app.UiThreadHandler;
|
||||||
_app = app;
|
_app = app;
|
||||||
@@ -84,7 +97,7 @@ namespace keepass2android
|
|||||||
// Set code to run when this is finished
|
// Set code to run when this is finished
|
||||||
_task.operationFinishedHandler = new AfterTask(app, task.operationFinishedHandler, _handler, this);
|
_task.operationFinishedHandler = new AfterTask(app, task.operationFinishedHandler, _handler, this);
|
||||||
|
|
||||||
_task.SetStatusLogger(_progressDialogStatusLogger);
|
_task.SetStatusLogger(_statusLogger);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -94,12 +107,12 @@ namespace keepass2android
|
|||||||
string currentMessage = "Initializing...";
|
string currentMessage = "Initializing...";
|
||||||
string currentSubmessage = "";
|
string currentSubmessage = "";
|
||||||
|
|
||||||
if (_progressDialogStatusLogger != null)
|
if (_statusLogger != null)
|
||||||
{
|
{
|
||||||
currentMessage = _progressDialogStatusLogger.Message;
|
currentMessage = _statusLogger.LastMessage;
|
||||||
currentSubmessage = _progressDialogStatusLogger.SubMessage;
|
currentSubmessage = _statusLogger.LastSubMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_progressDialog != null)
|
if (_progressDialog != null)
|
||||||
{
|
{
|
||||||
var pd = _progressDialog;
|
var pd = _progressDialog;
|
||||||
@@ -110,11 +123,21 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show process dialog
|
// Show process dialog
|
||||||
_progressDialog = app.CreateProgressDialog(_activeActivity);
|
_progressDialog = app.CreateProgressDialog(_activeContext);
|
||||||
_progressDialog.SetTitle(_app.GetResourceString(UiStringKey.progress_title));
|
|
||||||
_progressDialogStatusLogger = new ProgressDialogStatusLogger(_app, _handler, _progressDialog);
|
var progressUi = new ProgressDialogUi(_app, app.UiThreadHandler, _progressDialog);
|
||||||
_progressDialogStatusLogger.UpdateMessage(currentMessage);
|
if (_statusLogger == null)
|
||||||
_progressDialogStatusLogger.UpdateSubMessage(currentSubmessage);
|
{
|
||||||
|
_statusLogger = new ProgressUiAsStatusLoggerAdapter(progressUi, app);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_statusLogger.SetNewProgressUi(progressUi);
|
||||||
|
}
|
||||||
|
|
||||||
|
_statusLogger.StartLogging("", false);
|
||||||
|
_statusLogger.UpdateMessage(currentMessage);
|
||||||
|
_statusLogger.UpdateSubMessage(currentSubmessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run(bool allowOverwriteCurrentTask = false)
|
public void Run(bool allowOverwriteCurrentTask = false)
|
||||||
|
|||||||
@@ -143,5 +143,10 @@ namespace keepass2android
|
|||||||
|
|
||||||
ReaderWriterLockSlim DatabasesBackgroundModificationLock { get; }
|
ReaderWriterLockSlim DatabasesBackgroundModificationLock { get; }
|
||||||
bool CancelBackgroundOperations();
|
bool CancelBackgroundOperations();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Registers an action that should be executed when the context instance with the given id has been resumed.
|
||||||
|
/// </summary>
|
||||||
|
void RegisterPendingActionForContextInstance(int contextInstanceId, ActionOnOperationFinished actionToPerformWhenContextIsResumed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,8 @@ namespace keepass2android
|
|||||||
public interface IKp2aStatusLogger : IStatusLogger
|
public interface IKp2aStatusLogger : IStatusLogger
|
||||||
{
|
{
|
||||||
void UpdateMessage(UiStringKey stringKey);
|
void UpdateMessage(UiStringKey stringKey);
|
||||||
|
string LastMessage { get; }
|
||||||
|
string LastSubMessage { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IProgressUi
|
public interface IProgressUi
|
||||||
@@ -62,14 +64,16 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _lastMessage;
|
||||||
|
private string _lastSubMessage;
|
||||||
public void UpdateMessage(string message)
|
public void UpdateMessage(string message)
|
||||||
{
|
{
|
||||||
|
_lastMessage = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSubMessage(string submessage)
|
public void UpdateSubMessage(string submessage)
|
||||||
{
|
{
|
||||||
|
_lastSubMessage = submessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContinueWork()
|
public bool ContinueWork()
|
||||||
@@ -81,133 +85,88 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class Kp2aAppStatusLogger : IKp2aStatusLogger
|
|
||||||
{
|
|
||||||
protected IKp2aApp _app;
|
|
||||||
|
|
||||||
public Kp2aAppStatusLogger(IKp2aApp app)
|
|
||||||
{
|
|
||||||
_app = app;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region IStatusLogger implementation
|
|
||||||
|
|
||||||
public void StartLogging(string strOperation, bool bWriteOperationToLog)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndLogging()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SetProgress(uint uPercent)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool SetText(string strNewText, LogStatusType lsType)
|
|
||||||
{
|
|
||||||
if (strNewText.StartsWith("KP2AKEY_"))
|
|
||||||
{
|
|
||||||
UiStringKey key;
|
|
||||||
if (Enum.TryParse(strNewText.Substring("KP2AKEY_".Length), true, out key))
|
|
||||||
{
|
|
||||||
UpdateMessage(_app.GetResourceString(key), lsType);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UpdateMessage(strNewText, lsType);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void UpdateMessage(string message);
|
|
||||||
public abstract void UpdateSubMessage(string submessage);
|
|
||||||
|
|
||||||
private void UpdateMessage(string message, LogStatusType lsType)
|
|
||||||
{
|
|
||||||
if (lsType == LogStatusType.AdditionalInfo)
|
|
||||||
{
|
|
||||||
UpdateSubMessage(message);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UpdateMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool ContinueWork()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void UpdateMessage(UiStringKey stringKey)
|
|
||||||
{
|
|
||||||
if (_app != null)
|
|
||||||
UpdateMessage(_app.GetResourceString(stringKey));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string LastMessage { get { return _lastMessage; } }
|
||||||
|
public string LastSubMessage { get { return _lastSubMessage; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// StatusLogger implementation which shows the progress in a progress dialog
|
/// StatusLogger implementation which shows the progress in a progress dialog
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProgressDialogStatusLogger: Kp2aAppStatusLogger
|
public class ProgressDialogUi: IProgressUi
|
||||||
{
|
{
|
||||||
private readonly IProgressDialog _progressDialog;
|
private readonly IProgressDialog _progressDialog;
|
||||||
|
|
||||||
private readonly Handler _handler;
|
private readonly Handler _handler;
|
||||||
private string _message = "";
|
private string _message = "";
|
||||||
private string _submessage;
|
private string _submessage;
|
||||||
|
private readonly IKp2aApp _app;
|
||||||
|
|
||||||
public String SubMessage => _submessage;
|
public String LastSubMessage => _submessage;
|
||||||
public String Message => _message;
|
public String LastMessage => _message;
|
||||||
|
|
||||||
|
|
||||||
public ProgressDialogStatusLogger(IKp2aApp app, Handler handler, IProgressDialog pd)
|
public ProgressDialogUi(IKp2aApp app, Handler handler, IProgressDialog pd)
|
||||||
: base(app){
|
{
|
||||||
|
_app = app;
|
||||||
_progressDialog = pd;
|
_progressDialog = pd;
|
||||||
_handler = handler;
|
_handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateSubMessage(String submessage)
|
||||||
public override void UpdateMessage (String message)
|
{
|
||||||
{
|
Kp2aLog.Log("status submessage: " + submessage);
|
||||||
Kp2aLog.Log("status message: " + message);
|
_submessage = submessage;
|
||||||
|
if (_app != null && _progressDialog != null && _handler != null)
|
||||||
|
{
|
||||||
|
_handler.Post(() =>
|
||||||
|
{
|
||||||
|
if (!String.IsNullOrEmpty(submessage))
|
||||||
|
{
|
||||||
|
_progressDialog.SetMessage(_message + " (" + submessage + ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog.SetMessage(_message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Show()
|
||||||
|
{
|
||||||
|
_handler.Post(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
_progressDialog?.Show();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Hide()
|
||||||
|
{
|
||||||
|
_handler.Post(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
_progressDialog?.Dismiss();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMessage(string message)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log("status message: " + message);
|
||||||
_message = message;
|
_message = message;
|
||||||
if ( _app!= null && _progressDialog != null && _handler != null ) {
|
if (_app != null && _progressDialog != null && _handler != null)
|
||||||
_handler.Post(() => {_progressDialog.SetMessage(message); } );
|
{
|
||||||
}
|
_handler.Post(() => { _progressDialog.SetMessage(message); });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void UpdateSubMessage(String submessage)
|
}
|
||||||
{
|
|
||||||
Kp2aLog.Log("status submessage: " + submessage);
|
|
||||||
_submessage = submessage;
|
|
||||||
if (_app != null && _progressDialog != null && _handler != null)
|
|
||||||
{
|
|
||||||
_handler.Post(() =>
|
|
||||||
{
|
|
||||||
if (!String.IsNullOrEmpty(submessage))
|
|
||||||
{
|
|
||||||
_progressDialog.SetMessage(_message + " (" + submessage + ")");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_progressDialog.SetMessage(_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -87,4 +87,7 @@ public class ProgressUiAsStatusLoggerAdapter : IKp2aStatusLogger
|
|||||||
if (_app != null)
|
if (_app != null)
|
||||||
UpdateMessage(_app.GetResourceString(stringKey));
|
UpdateMessage(_app.GetResourceString(stringKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string LastMessage { get { return _lastMessage; } }
|
||||||
|
public string LastSubMessage { get { return _lastSubMessage; } }
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ using System;
|
|||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
|
using keepass2android;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@@ -53,3 +54,30 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ActionInContextInstanceOnOperationFinished : ActionOnOperationFinished
|
||||||
|
{
|
||||||
|
private readonly int _contextInstanceId;
|
||||||
|
private IKp2aApp _app;
|
||||||
|
|
||||||
|
public ActionInContextInstanceOnOperationFinished(int contextInstanceId, IKp2aApp app, ActionToPerformOnFinsh actionToPerform) : base(app, actionToPerform)
|
||||||
|
{
|
||||||
|
_contextInstanceId = contextInstanceId;
|
||||||
|
_app = app;
|
||||||
|
}
|
||||||
|
public ActionInContextInstanceOnOperationFinished(int contextInstanceId, IKp2aApp app, ActionToPerformOnFinsh actionToPerform, OnOperationFinishedHandler operationFinishedHandler) : base(app, actionToPerform, operationFinishedHandler)
|
||||||
|
{
|
||||||
|
_contextInstanceId = contextInstanceId;
|
||||||
|
_app = app;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Run()
|
||||||
|
{
|
||||||
|
if ((ActiveContext as IContextInstanceIdProvider)?.ContextInstanceId != _contextInstanceId)
|
||||||
|
{
|
||||||
|
_app.RegisterPendingActionForContextInstance(_contextInstanceId, this);
|
||||||
|
}
|
||||||
|
else base.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace keepass2android;
|
||||||
|
|
||||||
|
// A context instance can be the instance of an Activity. Even if the activity is recreated (due to a configuration change, for example), the instance id must remain the same
|
||||||
|
// but it must be different for other activities/services or if the activity is finished and then starts again.
|
||||||
|
// We want to be able to perform actions on a context instance, even though that instance might not live at the time when we want to perform the action.
|
||||||
|
// In that case, we want to be able to register the action such that it is performed when the activity is recreated.
|
||||||
|
public interface IContextInstanceIdProvider
|
||||||
|
{
|
||||||
|
|
||||||
|
int ContextInstanceId { get; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -551,9 +551,9 @@ namespace keepass2android
|
|||||||
//make sure we can close the EntryEditActivity activity even if the app went to background till we get to the OnOperationFinishedHandler Action
|
//make sure we can close the EntryEditActivity activity even if the app went to background till we get to the OnOperationFinishedHandler Action
|
||||||
|
|
||||||
|
|
||||||
ActionOnOperationFinished afterAddEntry = new ActionOnOperationFinished(App.Kp2a, (success, message, activity) =>
|
ActionOnOperationFinished afterAddEntry = new ActionInContextInstanceOnOperationFinished(ContextInstanceId, App.Kp2a, (success, message, context) =>
|
||||||
{
|
{
|
||||||
if (success && activity is EntryEditActivity entryEditActivity)
|
if (success && context is EntryEditActivity entryEditActivity)
|
||||||
AppTask.AfterAddNewEntry(entryEditActivity, newEntry);
|
AppTask.AfterAddNewEntry(entryEditActivity, newEntry);
|
||||||
},closeOrShowError);
|
},closeOrShowError);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ using Android.Runtime;
|
|||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class LifecycleAwareActivity : AndroidX.AppCompat.App.AppCompatActivity
|
public abstract class LifecycleAwareActivity : AndroidX.AppCompat.App.AppCompatActivity, IContextInstanceIdProvider
|
||||||
{
|
{
|
||||||
protected override void AttachBaseContext(Context baseContext)
|
protected override void AttachBaseContext(Context baseContext)
|
||||||
{
|
{
|
||||||
@@ -84,12 +84,11 @@ namespace keepass2android
|
|||||||
return baseRes;
|
return baseRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action? OnResumeListener { get; set; }
|
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
{
|
{
|
||||||
base.OnResume();
|
base.OnResume();
|
||||||
OnResumeListener?.Invoke();
|
App.Kp2a.PerformPendingActions(_instanceId);
|
||||||
|
|
||||||
Kp2aLog.Log(ClassName + ".OnResume " + ID);
|
Kp2aLog.Log(ClassName + ".OnResume " + ID);
|
||||||
if (App.Kp2a.CurrentDb == null)
|
if (App.Kp2a.CurrentDb == null)
|
||||||
@@ -105,28 +104,40 @@ namespace keepass2android
|
|||||||
protected override void OnStart()
|
protected override void OnStart()
|
||||||
{
|
{
|
||||||
App.Kp2a.ActiveContext = this;
|
App.Kp2a.ActiveContext = this;
|
||||||
BlockingOperationRunner.SetNewActiveActivity(this);
|
BlockingOperationRunner.SetNewActiveContext(this);
|
||||||
BackgroundOperationRunner.Instance.SetNewActiveContext( App.Kp2a);
|
BackgroundOperationRunner.Instance.SetNewActiveContext( App.Kp2a);
|
||||||
|
|
||||||
base.OnStart();
|
base.OnStart();
|
||||||
Kp2aLog.Log(ClassName + ".OnStart" + " " + ID);
|
Kp2aLog.Log(ClassName + ".OnStart" + " " + ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string ID_KEY = "kp2a_context_instance_id";
|
||||||
|
const int InvalidId = -1;
|
||||||
|
|
||||||
|
private int _instanceId;
|
||||||
|
|
||||||
protected override void OnCreate(Bundle bundle)
|
protected override void OnCreate(Bundle bundle)
|
||||||
{
|
{
|
||||||
|
|
||||||
base.OnCreate(bundle);
|
base.OnCreate(bundle);
|
||||||
|
|
||||||
|
_instanceId = bundle?.GetInt(ID_KEY, InvalidId) ?? InvalidId;
|
||||||
|
if (_instanceId == InvalidId)
|
||||||
|
{
|
||||||
|
_instanceId = _nextContextInstanceId++;
|
||||||
|
}
|
||||||
|
|
||||||
OnCreateListener?.Invoke(bundle);
|
OnCreateListener?.Invoke(bundle);
|
||||||
|
|
||||||
Kp2aLog.Log(ClassName + ".OnCreate" + " " + ID);
|
Kp2aLog.Log(ClassName + ".OnCreate" + " " + ID + " (instance=" + _instanceId +")");
|
||||||
Kp2aLog.Log(ClassName + ":apptask=" + Intent.GetStringExtra("KP2A_APP_TASK_TYPE") + " " + ID);
|
Kp2aLog.Log(ClassName + ":apptask=" + Intent.GetStringExtra("KP2A_APP_TASK_TYPE") + " " + ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void OnDestroy()
|
protected override void OnDestroy()
|
||||||
{
|
{
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
Kp2aLog.Log(ClassName + ".OnDestroy" + IsFinishing.ToString() + " " + ID);
|
Kp2aLog.Log(ClassName + ".OnDestroy " + IsFinishing.ToString() + " " + ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
@@ -139,14 +150,19 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
base.OnStop();
|
base.OnStop();
|
||||||
Kp2aLog.Log(ClassName + ".OnStop" + " " + ID);
|
Kp2aLog.Log(ClassName + ".OnStop" + " " + ID);
|
||||||
BlockingOperationRunner.RemoveActiveActivity(this);
|
BlockingOperationRunner.RemoveActiveContext(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnSaveInstanceState(Bundle outState)
|
protected override void OnSaveInstanceState(Bundle outState)
|
||||||
{
|
{
|
||||||
base.OnSaveInstanceState(outState);
|
base.OnSaveInstanceState(outState);
|
||||||
|
outState.PutInt(ID_KEY, _instanceId);
|
||||||
OnSaveInstanceStateListener?.Invoke(outState);
|
OnSaveInstanceStateListener?.Invoke(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _nextContextInstanceId = 0;
|
||||||
|
|
||||||
|
public int ContextInstanceId => _instanceId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ namespace keepass2android
|
|||||||
private bool _isShowingUserInputDialog = false;
|
private bool _isShowingUserInputDialog = false;
|
||||||
private IMessagePresenter? _messagePresenter;
|
private IMessagePresenter? _messagePresenter;
|
||||||
private YesNoCancelQuestion? _currentlyPendingYesNoCancelQuestion = null;
|
private YesNoCancelQuestion? _currentlyPendingYesNoCancelQuestion = null;
|
||||||
private Context _activeContext;
|
private Context? _activeContext;
|
||||||
|
|
||||||
private void AskForReload(Activity activity, Action<bool> actionOnResult)
|
private void AskForReload(Activity activity, Action<bool> actionOnResult)
|
||||||
{
|
{
|
||||||
@@ -882,8 +882,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
public IProgressDialog CreateProgressDialog(Context ctx)
|
public IProgressDialog CreateProgressDialog(Context ctx)
|
||||||
{
|
{
|
||||||
return new RealProgressDialog(ctx, this);
|
var pd = new RealProgressDialog(ctx, this);
|
||||||
}
|
pd.SetTitle(GetResourceString(UiStringKey.progress_title));
|
||||||
|
return pd;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public IFileStorage GetFileStorage(IOConnectionInfo iocInfo)
|
public IFileStorage GetFileStorage(IOConnectionInfo iocInfo)
|
||||||
{
|
{
|
||||||
@@ -1480,7 +1483,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
public Context ActiveContext
|
public Context ActiveContext
|
||||||
{
|
{
|
||||||
get => _activeContext;
|
get => _activeContext ?? Application.Context;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_activeContext = value;
|
_activeContext = value;
|
||||||
@@ -1513,6 +1516,47 @@ namespace keepass2android
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<int, List<ActionOnOperationFinished>> _pendingActionsForContextInstances = new();
|
||||||
|
private readonly object _pendingActionsForContextInstancesLock = new();
|
||||||
|
public void RegisterPendingActionForContextInstance(int contextInstanceId,
|
||||||
|
ActionOnOperationFinished actionToPerformWhenContextIsResumed)
|
||||||
|
{
|
||||||
|
lock (_pendingActionsForContextInstancesLock)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!_pendingActionsForContextInstances.TryGetValue(contextInstanceId, out var actions))
|
||||||
|
{
|
||||||
|
actions = new List<ActionOnOperationFinished>();
|
||||||
|
_pendingActionsForContextInstances[contextInstanceId] = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
actions.Add(actionToPerformWhenContextIsResumed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PerformPendingActions(int instanceId)
|
||||||
|
{
|
||||||
|
lock (_pendingActionsForContextInstancesLock)
|
||||||
|
{
|
||||||
|
if (_pendingActionsForContextInstances.TryGetValue(instanceId, out var actions))
|
||||||
|
{
|
||||||
|
foreach (var action in actions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action.Run();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Kp2aLog.LogUnexpectedError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_pendingActionsForContextInstances.Remove(instanceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user