split file into one file per class
This commit is contained in:
125
src/Kp2aBusinessLogic/BackgroundOperationRunner.cs
Normal file
125
src/Kp2aBusinessLogic/BackgroundOperationRunner.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using Android.Content;
|
||||
using Thread = Java.Lang.Thread;
|
||||
|
||||
namespace keepass2android;
|
||||
|
||||
/// <summary>
|
||||
/// Allows to run tasks in the background. The UI is not blocked by the task. Tasks continue to run in the BackgroundSyncService if the app goes to background while tasks are active.
|
||||
/// </summary>
|
||||
public class BackgroundOperationRunner
|
||||
{
|
||||
//singleton instance
|
||||
private static BackgroundOperationRunner _instance = null;
|
||||
|
||||
public static BackgroundOperationRunner Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new BackgroundOperationRunner();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public ProgressUiAsStatusLoggerAdapter StatusLogger => _statusLogger;
|
||||
|
||||
private BackgroundOperationRunner()
|
||||
{
|
||||
//private constructor
|
||||
}
|
||||
|
||||
private readonly Queue<OperationWithFinishHandler> _taskQueue = new Queue<OperationWithFinishHandler>();
|
||||
private readonly object _taskQueueLock = new object();
|
||||
private Java.Lang.Thread? _thread = null;
|
||||
private OperationWithFinishHandler? _currentlyRunningTask = null;
|
||||
private ProgressUiAsStatusLoggerAdapter _statusLogger = null;
|
||||
|
||||
public void Run(IKp2aApp app, OperationWithFinishHandler operation)
|
||||
{
|
||||
lock (Instance._taskQueueLock)
|
||||
{
|
||||
_taskQueue.Enqueue(operation);
|
||||
SetNewActiveContext(app);
|
||||
|
||||
// Start thread to run the task (unless it's already running)
|
||||
if (_thread == null)
|
||||
{
|
||||
_statusLogger.StartLogging("", false);
|
||||
_thread = new Java.Lang.Thread(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
||||
lock (_taskQueueLock)
|
||||
{
|
||||
if (!_taskQueue.Any())
|
||||
{
|
||||
_thread = null;
|
||||
_statusLogger.EndLogging();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentlyRunningTask = _taskQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
var originalFinishedHandler = _currentlyRunningTask.operationFinishedHandler;
|
||||
_currentlyRunningTask.operationFinishedHandler = new ActionOnOperationFinished(app, (
|
||||
(success, message, context) =>
|
||||
{
|
||||
_currentlyRunningTask = null;
|
||||
}), originalFinishedHandler);
|
||||
_currentlyRunningTask.Run();
|
||||
while (_currentlyRunningTask != null)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetNewActiveContext(IKp2aApp app)
|
||||
{
|
||||
Context? context = app.ActiveContext;
|
||||
lock (_taskQueueLock)
|
||||
{
|
||||
if (context == null && _thread != null)
|
||||
{
|
||||
//this will register the service as new active context
|
||||
app.StartBackgroundSyncService();
|
||||
return;
|
||||
}
|
||||
|
||||
var progressUi = (context as IProgressUiProvider)?.ProgressUi;
|
||||
if (_statusLogger == null)
|
||||
{
|
||||
_statusLogger = new ProgressUiAsStatusLoggerAdapter(progressUi, app);
|
||||
}
|
||||
else
|
||||
{
|
||||
_statusLogger.SetNewProgressUi(progressUi);
|
||||
}
|
||||
|
||||
foreach (var task in _taskQueue.Concat(_currentlyRunningTask == null ?
|
||||
new List<OperationWithFinishHandler>() :
|
||||
new List<OperationWithFinishHandler>() { _currentlyRunningTask })
|
||||
)
|
||||
{
|
||||
task.SetStatusLogger(_statusLogger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,219 +20,10 @@ using Android.Content;
|
||||
using Android.OS;
|
||||
using Java.Lang;
|
||||
using Java.Security;
|
||||
using KeePassLib.Interfaces;
|
||||
using System.Threading.Tasks;
|
||||
using Enum = System.Enum;
|
||||
using Thread = Java.Lang.Thread;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
public class BackgroundOperationRunner
|
||||
{
|
||||
//singleton instance
|
||||
private static BackgroundOperationRunner _instance = null;
|
||||
|
||||
public static BackgroundOperationRunner Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new BackgroundOperationRunner();
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public ProgressUiAsStatusLoggerAdapter StatusLogger => _statusLogger;
|
||||
|
||||
private BackgroundOperationRunner()
|
||||
{
|
||||
//private constructor
|
||||
}
|
||||
|
||||
private readonly Queue<OperationWithFinishHandler> _taskQueue = new Queue<OperationWithFinishHandler>();
|
||||
private readonly object _taskQueueLock = new object();
|
||||
private Java.Lang.Thread? _thread = null;
|
||||
private OperationWithFinishHandler? _currentlyRunningTask = null;
|
||||
private ProgressUiAsStatusLoggerAdapter _statusLogger = null;
|
||||
|
||||
public void Run(IKp2aApp app, OperationWithFinishHandler operation)
|
||||
{
|
||||
lock (Instance._taskQueueLock)
|
||||
{
|
||||
_taskQueue.Enqueue(operation);
|
||||
SetNewActiveContext(app);
|
||||
|
||||
// Start thread to run the task (unless it's already running)
|
||||
if (_thread == null)
|
||||
{
|
||||
_statusLogger.StartLogging("", false);
|
||||
_thread = new Java.Lang.Thread(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
||||
lock (_taskQueueLock)
|
||||
{
|
||||
if (!_taskQueue.Any())
|
||||
{
|
||||
_thread = null;
|
||||
_statusLogger.EndLogging();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentlyRunningTask = _taskQueue.Dequeue();
|
||||
}
|
||||
}
|
||||
|
||||
var originalFinishedHandler = _currentlyRunningTask.operationFinishedHandler;
|
||||
_currentlyRunningTask.operationFinishedHandler = new ActionOnOperationFinished(app, (
|
||||
(success, message, context) =>
|
||||
{
|
||||
_currentlyRunningTask = null;
|
||||
}), originalFinishedHandler);
|
||||
_currentlyRunningTask.Run();
|
||||
while (_currentlyRunningTask != null)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetNewActiveContext(IKp2aApp app)
|
||||
{
|
||||
Context? context = app.ActiveContext;
|
||||
lock (_taskQueueLock)
|
||||
{
|
||||
if (context == null && _thread != null)
|
||||
{
|
||||
//this will register the service as new active context
|
||||
app.StartBackgroundSyncService();
|
||||
return;
|
||||
}
|
||||
|
||||
var progressUi = (context as IProgressUiProvider)?.ProgressUi;
|
||||
if (_statusLogger == null)
|
||||
{
|
||||
_statusLogger = new ProgressUiAsStatusLoggerAdapter(progressUi, app);
|
||||
}
|
||||
else
|
||||
{
|
||||
_statusLogger.SetNewProgressUi(progressUi);
|
||||
}
|
||||
|
||||
foreach (var task in _taskQueue.Concat(_currentlyRunningTask == null ?
|
||||
new List<OperationWithFinishHandler>() :
|
||||
new List<OperationWithFinishHandler>() { _currentlyRunningTask })
|
||||
)
|
||||
{
|
||||
task.SetStatusLogger(_statusLogger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class ProgressUiAsStatusLoggerAdapter : IKp2aStatusLogger
|
||||
{
|
||||
private IProgressUi? _progressUi;
|
||||
private readonly IKp2aApp _app;
|
||||
|
||||
private string _lastMessage = "";
|
||||
private string _lastSubMessage = "";
|
||||
private bool _isVisible = false;
|
||||
|
||||
public ProgressUiAsStatusLoggerAdapter(IProgressUi progressUi, IKp2aApp app)
|
||||
{
|
||||
_progressUi = progressUi;
|
||||
_app = app;
|
||||
}
|
||||
|
||||
public void SetNewProgressUi(IProgressUi progressUi)
|
||||
{
|
||||
_progressUi = progressUi;
|
||||
if (_isVisible)
|
||||
{
|
||||
progressUi?.Show();
|
||||
progressUi?.UpdateMessage(_lastMessage);
|
||||
progressUi?.UpdateSubMessage(_lastSubMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
progressUi?.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartLogging(string strOperation, bool bWriteOperationToLog)
|
||||
{
|
||||
_progressUi?.Show();
|
||||
_isVisible = true;
|
||||
}
|
||||
|
||||
public void EndLogging()
|
||||
{
|
||||
_progressUi?.Hide();
|
||||
_isVisible = false;
|
||||
}
|
||||
|
||||
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));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
UpdateMessage(strNewText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateMessage(string message)
|
||||
{
|
||||
_progressUi?.UpdateMessage(message);
|
||||
_lastMessage = message;
|
||||
}
|
||||
|
||||
public void UpdateSubMessage(string submessage)
|
||||
{
|
||||
_progressUi?.UpdateSubMessage(submessage);
|
||||
_lastSubMessage = submessage;
|
||||
}
|
||||
|
||||
public bool ContinueWork()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateMessage(UiStringKey stringKey)
|
||||
{
|
||||
if (_app != null)
|
||||
UpdateMessage(_app.GetResourceString(stringKey));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Class to run a task while a progress dialog is shown
|
||||
/// </summary>
|
||||
|
||||
90
src/Kp2aBusinessLogic/ProgressUiAsStatusLoggerAdapter.cs
Normal file
90
src/Kp2aBusinessLogic/ProgressUiAsStatusLoggerAdapter.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using KeePassLib.Interfaces;
|
||||
|
||||
namespace keepass2android;
|
||||
|
||||
public class ProgressUiAsStatusLoggerAdapter : IKp2aStatusLogger
|
||||
{
|
||||
private IProgressUi? _progressUi;
|
||||
private readonly IKp2aApp _app;
|
||||
|
||||
private string _lastMessage = "";
|
||||
private string _lastSubMessage = "";
|
||||
private bool _isVisible = false;
|
||||
|
||||
public ProgressUiAsStatusLoggerAdapter(IProgressUi progressUi, IKp2aApp app)
|
||||
{
|
||||
_progressUi = progressUi;
|
||||
_app = app;
|
||||
}
|
||||
|
||||
public void SetNewProgressUi(IProgressUi progressUi)
|
||||
{
|
||||
_progressUi = progressUi;
|
||||
if (_isVisible)
|
||||
{
|
||||
progressUi?.Show();
|
||||
progressUi?.UpdateMessage(_lastMessage);
|
||||
progressUi?.UpdateSubMessage(_lastSubMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
progressUi?.Hide();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartLogging(string strOperation, bool bWriteOperationToLog)
|
||||
{
|
||||
_progressUi?.Show();
|
||||
_isVisible = true;
|
||||
}
|
||||
|
||||
public void EndLogging()
|
||||
{
|
||||
_progressUi?.Hide();
|
||||
_isVisible = false;
|
||||
}
|
||||
|
||||
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));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
UpdateMessage(strNewText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateMessage(string message)
|
||||
{
|
||||
_progressUi?.UpdateMessage(message);
|
||||
_lastMessage = message;
|
||||
}
|
||||
|
||||
public void UpdateSubMessage(string submessage)
|
||||
{
|
||||
_progressUi?.UpdateSubMessage(submessage);
|
||||
_lastSubMessage = submessage;
|
||||
}
|
||||
|
||||
public bool ContinueWork()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void UpdateMessage(UiStringKey stringKey)
|
||||
{
|
||||
if (_app != null)
|
||||
UpdateMessage(_app.GetResourceString(stringKey));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user