let database sync run in the background. not handling all cases yet.
This commit is contained in:
		@@ -19,9 +19,195 @@ using Android.App;
 | 
				
			|||||||
using Android.Content;
 | 
					using Android.Content;
 | 
				
			||||||
using Android.OS;
 | 
					using Android.OS;
 | 
				
			||||||
using Java.Lang;
 | 
					using Java.Lang;
 | 
				
			||||||
 | 
					using Java.Security;
 | 
				
			||||||
 | 
					using KeePassLib.Interfaces;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Enum = System.Enum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace keepass2android
 | 
					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;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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 ProgressUiAsStatusLoggerAdapter _statusLogger = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Run(Activity activity, IKp2aApp app, OperationWithFinishHandler operation)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            lock (Instance._taskQueueLock)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _taskQueue.Enqueue(operation);
 | 
				
			||||||
 | 
					                SetNewActiveActivity(activity, 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)
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            OperationWithFinishHandler task;
 | 
				
			||||||
 | 
					                            lock (_taskQueueLock)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if (!_taskQueue.Any())
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    _thread = null;
 | 
				
			||||||
 | 
					                                    _statusLogger.EndLogging();
 | 
				
			||||||
 | 
					                                    break;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                                else
 | 
				
			||||||
 | 
					                                {
 | 
				
			||||||
 | 
					                                    task = _taskQueue.Dequeue();
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            task.Run();
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    _thread.Start();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					               
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void SetNewActiveActivity(Activity? activity, IKp2aApp app)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            lock (_taskQueueLock)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var progressUi = (activity as IProgressUiProvider)?.ProgressUi;
 | 
				
			||||||
 | 
					                if (_statusLogger == null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _statusLogger = new ProgressUiAsStatusLoggerAdapter(progressUi, app);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _statusLogger.SetNewProgressUi(progressUi);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
					                foreach (var task in _taskQueue)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
										task.ActiveActivity = activity;
 | 
				
			||||||
 | 
										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>
 | 
					    /// <summary>
 | 
				
			||||||
        /// Class to run a task while a progress dialog is shown
 | 
					        /// Class to run a task while a progress dialog is shown
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,20 @@ namespace keepass2android
 | 
				
			|||||||
        void UpdateMessage(UiStringKey stringKey);
 | 
					        void UpdateMessage(UiStringKey stringKey);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface IProgressUi
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        void Show();
 | 
				
			||||||
 | 
					        void Hide();
 | 
				
			||||||
 | 
					        void UpdateMessage(String message);
 | 
				
			||||||
 | 
					        void UpdateSubMessage(String submessage);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface IProgressUiProvider
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        IProgressUi? ProgressUi { get; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class Kp2aNullStatusLogger : IKp2aStatusLogger
 | 
					    public class Kp2aNullStatusLogger : IKp2aStatusLogger
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public void StartLogging(string strOperation, bool bWriteOperationToLog)
 | 
					        public void StartLogging(string strOperation, bool bWriteOperationToLog)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,6 +56,7 @@ using Android.Util;
 | 
				
			|||||||
using AndroidX.Core.Content;
 | 
					using AndroidX.Core.Content;
 | 
				
			||||||
using Google.Android.Material.Dialog;
 | 
					using Google.Android.Material.Dialog;
 | 
				
			||||||
using keepass2android;
 | 
					using keepass2android;
 | 
				
			||||||
 | 
					using keepass2android.views;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace keepass2android
 | 
					namespace keepass2android
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -97,7 +98,7 @@ namespace keepass2android
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	[Activity (Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden,
 | 
						[Activity (Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden,
 | 
				
			||||||
        Theme = "@style/Kp2aTheme_ActionBar")]
 | 
					        Theme = "@style/Kp2aTheme_ActionBar")]
 | 
				
			||||||
	public class EntryActivity : LockCloseActivity 
 | 
						public class EntryActivity : LockCloseActivity, IProgressUiProvider
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		public const String KeyEntry = "entry";
 | 
							public const String KeyEntry = "entry";
 | 
				
			||||||
        public const String KeyRefreshPos = "refresh_pos";
 | 
					        public const String KeyRefreshPos = "refresh_pos";
 | 
				
			||||||
@@ -1603,5 +1604,7 @@ namespace keepass2android
 | 
				
			|||||||
			imageViewerIntent.PutExtra("EntryKey", key);
 | 
								imageViewerIntent.PutExtra("EntryKey", key);
 | 
				
			||||||
			StartActivity(imageViewerIntent);
 | 
								StartActivity(imageViewerIntent);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IProgressUi? ProgressUi => FindViewById<BackgroundOperationContainer>(Resource.Id.background_ops_container);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -43,11 +43,12 @@ using keepass2android;
 | 
				
			|||||||
using KeeTrayTOTP.Libraries;
 | 
					using KeeTrayTOTP.Libraries;
 | 
				
			||||||
using AndroidX.AppCompat.Widget;
 | 
					using AndroidX.AppCompat.Widget;
 | 
				
			||||||
using Google.Android.Material.Dialog;
 | 
					using Google.Android.Material.Dialog;
 | 
				
			||||||
 | 
					using keepass2android.views;
 | 
				
			||||||
using SearchView = AndroidX.AppCompat.Widget.SearchView;
 | 
					using SearchView = AndroidX.AppCompat.Widget.SearchView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace keepass2android
 | 
					namespace keepass2android
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public abstract class GroupBaseActivity : LockCloseActivity
 | 
					    public abstract class GroupBaseActivity : LockCloseActivity, IProgressUiProvider
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        public const String KeyEntry = "entry";
 | 
					        public const String KeyEntry = "entry";
 | 
				
			||||||
        public const String KeyMode = "mode";
 | 
					        public const String KeyMode = "mode";
 | 
				
			||||||
@@ -1408,6 +1409,14 @@ namespace keepass2android
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            GroupEditActivity.Launch(this, pwGroup.ParentGroup, pwGroup);
 | 
					            GroupEditActivity.Launch(this, pwGroup.ParentGroup, pwGroup);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IProgressUi ProgressUi
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            get
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return FindViewById<BackgroundOperationContainer>(Resource.Id.background_ops_container);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
 | 
					    public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -105,6 +105,7 @@ namespace keepass2android
 | 
				
			|||||||
        protected override void OnStart()
 | 
					        protected override void OnStart()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            BlockingOperationRunner.SetNewActiveActivity(this);
 | 
					            BlockingOperationRunner.SetNewActiveActivity(this);
 | 
				
			||||||
 | 
					            BackgroundOperationRunner.Instance.SetNewActiveActivity(this, App.Kp2a);
 | 
				
			||||||
            base.OnStart();
 | 
					            base.OnStart();
 | 
				
			||||||
            Kp2aLog.Log(ClassName + ".OnStart" + " " + ID);
 | 
					            Kp2aLog.Log(ClassName + ".OnStart" + " " + ID);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
				
			||||||
 | 
					    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
				
			||||||
 | 
						xmlns:tools="http://schemas.android.com/tools"
 | 
				
			||||||
 | 
					    android:id="@+id/background_ops_container"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					    android:background="@color/md_theme_surfaceVariant"
 | 
				
			||||||
 | 
					    android:orientation="vertical"   
 | 
				
			||||||
 | 
					>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    <com.google.android.material.progressindicator.LinearProgressIndicator
 | 
				
			||||||
 | 
					      android:layout_width="match_parent"
 | 
				
			||||||
 | 
					      android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					      android:indeterminate="true" />
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <TextView 
 | 
				
			||||||
 | 
					      android:id="@+id/background_ops_message"
 | 
				
			||||||
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					              android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					              android:layout_marginLeft="10dp"
 | 
				
			||||||
 | 
					              android:layout_marginRight="10dp"
 | 
				
			||||||
 | 
					              android:layout_marginTop="0dp"
 | 
				
			||||||
 | 
					              android:layout_marginBottom="3dp"
 | 
				
			||||||
 | 
					              android:text="" />
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <TextView 
 | 
				
			||||||
 | 
					      android:id="@+id/background_ops_submessage"
 | 
				
			||||||
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
 | 
					              android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					                android:layout_marginLeft="10dp"
 | 
				
			||||||
 | 
					                android:layout_marginRight="10dp"
 | 
				
			||||||
 | 
					                android:layout_marginTop="0dp"
 | 
				
			||||||
 | 
					                android:layout_marginBottom="3dp"
 | 
				
			||||||
 | 
					                android:textSize="12sp"
 | 
				
			||||||
 | 
					              android:text="" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  </LinearLayout>
 | 
				
			||||||
 | 
							
 | 
				
			||||||
@@ -4,18 +4,35 @@
 | 
				
			|||||||
    android:layout_width="match_parent"
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
    android:layout_height="match_parent"
 | 
					    android:layout_height="match_parent"
 | 
				
			||||||
    android:fitsSystemWindows="true">
 | 
					    android:fitsSystemWindows="true">
 | 
				
			||||||
 | 
					    <LinearLayout android:layout_width="fill_parent"
 | 
				
			||||||
 | 
					        android:layout_height="fill_parent"
 | 
				
			||||||
 | 
					        android:orientation="vertical">
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  <keepass2android.views.BackgroundOperationContainer
 | 
				
			||||||
 | 
					    android:visibility="gone"
 | 
				
			||||||
 | 
					    android:id="@+id/background_ops_container"
 | 
				
			||||||
 | 
					    android:layout_below="@id/top"
 | 
				
			||||||
 | 
					    android:layout_width="match_parent"
 | 
				
			||||||
 | 
					    android:layout_height="wrap_content"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  />
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    <ScrollView
 | 
					    <ScrollView
 | 
				
			||||||
        android:id="@+id/entry_scroll"
 | 
					        android:id="@+id/entry_scroll"
 | 
				
			||||||
        android:layout_width="fill_parent"
 | 
					        android:layout_width="fill_parent"
 | 
				
			||||||
        android:layout_height="fill_parent"
 | 
					        android:layout_height="fill_parent"
 | 
				
			||||||
        android:fillViewport="true"
 | 
					 | 
				
			||||||
        android:background="?android:attr/colorBackground"
 | 
					        android:background="?android:attr/colorBackground"
 | 
				
			||||||
        android:scrollbarStyle="insideOverlay">
 | 
					        android:scrollbarStyle="insideOverlay">
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        <keepass2android.view.EntryContentsView
 | 
					        <keepass2android.view.EntryContentsView
 | 
				
			||||||
            android:id="@+id/entry_contents"
 | 
					            android:id="@+id/entry_contents"
 | 
				
			||||||
            android:layout_height="wrap_content"
 | 
					            android:layout_height="wrap_content"
 | 
				
			||||||
            android:layout_width="fill_parent" />
 | 
					            android:layout_width="fill_parent" />
 | 
				
			||||||
    </ScrollView>
 | 
					    </ScrollView>
 | 
				
			||||||
 | 
					    </LinearLayout>
 | 
				
			||||||
    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
					    <com.google.android.material.floatingactionbutton.FloatingActionButton
 | 
				
			||||||
        android:id="@+id/entry_edit"
 | 
					        android:id="@+id/entry_edit"
 | 
				
			||||||
        android:layout_width="wrap_content"
 | 
					        android:layout_width="wrap_content"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -355,29 +355,14 @@
 | 
				
			|||||||
        android:layout_above="@id/bottom_bar"
 | 
					        android:layout_above="@id/bottom_bar"
 | 
				
			||||||
        android:background="#b8b8b8" />
 | 
					        android:background="#b8b8b8" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <LinearLayout
 | 
					   <keepass2android.views.BackgroundOperationContainer
 | 
				
			||||||
 | 
					        android:visibility="gone"
 | 
				
			||||||
     android:id="@+id/background_ops_container"
 | 
					     android:id="@+id/background_ops_container"
 | 
				
			||||||
      android:layout_width="match_parent"
 | 
					 | 
				
			||||||
      android:layout_height="wrap_content"
 | 
					 | 
				
			||||||
      android:background="@color/md_theme_surfaceVariant"
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
     android:layout_below="@id/top"
 | 
					     android:layout_below="@id/top"
 | 
				
			||||||
      android:orientation="vertical" >
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      <com.google.android.material.progressindicator.LinearProgressIndicator
 | 
					 | 
				
			||||||
     android:layout_width="match_parent"
 | 
					     android:layout_width="match_parent"
 | 
				
			||||||
     android:layout_height="wrap_content"
 | 
					     android:layout_height="wrap_content"
 | 
				
			||||||
        android:indeterminate="true" />
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
      <TextView android:layout_width="wrap_content"
 | 
					 | 
				
			||||||
                android:layout_height="wrap_content"
 | 
					 | 
				
			||||||
                android:padding="10dp"
 | 
					 | 
				
			||||||
                android:text="Synchronisierung läuft..." />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </LinearLayout>
 | 
					 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    <androidx.coordinatorlayout.widget.CoordinatorLayout
 | 
					    <androidx.coordinatorlayout.widget.CoordinatorLayout
 | 
				
			||||||
        android:id="@+id/main_content"
 | 
					        android:id="@+id/main_content"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
using System;
 | 
					using System;
 | 
				
			||||||
using Android.App;
 | 
					using Android.App;
 | 
				
			||||||
 | 
					using Android.OS;
 | 
				
			||||||
using Android.Widget;
 | 
					using Android.Widget;
 | 
				
			||||||
using keepass2android.Io;
 | 
					using keepass2android.Io;
 | 
				
			||||||
using KeePassLib.Serialization;
 | 
					using KeePassLib.Serialization;
 | 
				
			||||||
@@ -56,17 +57,17 @@ namespace keepass2android
 | 
				
			|||||||
            OnOperationFinishedHandler onOperationFinishedHandler = new ActionOnOperationFinished(_activity, (success, message, activity) =>
 | 
					            OnOperationFinishedHandler onOperationFinishedHandler = new ActionOnOperationFinished(_activity, (success, message, activity) =>
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!String.IsNullOrEmpty(message))
 | 
					                if (!String.IsNullOrEmpty(message))
 | 
				
			||||||
                    App.Kp2a.ShowMessage(activity, message,  MessageSeverity.Error);
 | 
					                    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; 
 | 
				
			||||||
                adapter?.NotifyDataSetChanged();
 | 
					                new Handler(Looper.MainLooper).Post(() => adapter?.NotifyDataSetChanged());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null)
 | 
					                if (App.Kp2a.CurrentDb?.OtpAuxFileIoc != null)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    var task2 = new SyncOtpAuxFile(_activity, App.Kp2a.CurrentDb.OtpAuxFileIoc);
 | 
					                    var task2 = new SyncOtpAuxFile(_activity, App.Kp2a.CurrentDb.OtpAuxFileIoc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    //TODO new BackgroundOperationRunner(App.Kp2a, activity, task2).Run(true);
 | 
					                    BackgroundOperationRunner.Instance.Run(_activity, App.Kp2a, task2);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
               
 | 
					               
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
@@ -82,8 +83,7 @@ namespace keepass2android
 | 
				
			|||||||
                task = new CheckDatabaseForChanges(_activity, App.Kp2a, onOperationFinishedHandler);
 | 
					                task = new CheckDatabaseForChanges(_activity, App.Kp2a, onOperationFinishedHandler);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //TODO var backgroundTaskRunner = new BackgroundOperationRunner(App.Kp2a, _activity, task);
 | 
					            BackgroundOperationRunner.Instance.Run(_activity, App.Kp2a, task);
 | 
				
			||||||
            //TODO backgroundTaskRunner.Run();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ using Android.Views;
 | 
				
			|||||||
using Android.Widget;
 | 
					using Android.Widget;
 | 
				
			||||||
using Google.Android.Material.Dialog;
 | 
					using Google.Android.Material.Dialog;
 | 
				
			||||||
using keepass2android;
 | 
					using keepass2android;
 | 
				
			||||||
 | 
					using KeePassLib.Interfaces;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace keepass2android.views
 | 
					namespace keepass2android.views
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -103,4 +104,92 @@ namespace keepass2android.views
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class BackgroundOperationContainer : LinearLayout, IProgressUi
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        protected BackgroundOperationContainer(IntPtr javaReference, JniHandleOwnership transfer) : base(
 | 
				
			||||||
 | 
					            javaReference, transfer)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BackgroundOperationContainer(Context context) : base(context)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BackgroundOperationContainer(Context context, IAttributeSet attrs) : base(context, attrs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Initialize(attrs);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BackgroundOperationContainer(Context context, IAttributeSet attrs, int defStyle) : base(context,
 | 
				
			||||||
 | 
					            attrs, defStyle)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Initialize(attrs);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Initialize(IAttributeSet attrs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
 | 
				
			||||||
 | 
					            inflater.Inflate(Resource.Layout.background_operation_container, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Show()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            new Handler(Looper.MainLooper).Post(() =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Visibility = ViewStates.Visible;
 | 
				
			||||||
 | 
					                FindViewById<TextView>(Resource.Id.background_ops_message)!.Visibility = ViewStates.Gone;
 | 
				
			||||||
 | 
					                FindViewById<TextView>(Resource.Id.background_ops_submessage)!.Visibility = ViewStates.Gone;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Hide()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            new Handler(Looper.MainLooper).Post(() =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                String activityType = Context.GetType().FullName;
 | 
				
			||||||
 | 
					                Kp2aLog.Log("Hiding background ops container in" + activityType);
 | 
				
			||||||
 | 
					                Visibility = ViewStates.Gone;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void UpdateMessage(string message)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            new Handler(Looper.MainLooper).Post(() =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TextView messageTextView = FindViewById<TextView>(Resource.Id.background_ops_message)!;
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(message))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    messageTextView.Visibility = ViewStates.Gone;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    messageTextView.Visibility = ViewStates.Visible;
 | 
				
			||||||
 | 
					                    messageTextView.Text = message;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void UpdateSubMessage(string submessage)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            new Handler(Looper.MainLooper).Post(() =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                TextView subMessageTextView = FindViewById<TextView>(Resource.Id.background_ops_submessage)!;
 | 
				
			||||||
 | 
					                if (string.IsNullOrEmpty(submessage))
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    subMessageTextView.Visibility = ViewStates.Gone;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    subMessageTextView.Visibility = ViewStates.Visible;
 | 
				
			||||||
 | 
					                    subMessageTextView.Text = submessage;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user