From 6d51864873ebbb45815ce099809a92a6933b472c Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 30 May 2019 14:13:02 -0400 Subject: [PATCH] update tasks and sync on app start --- .../Receivers/PackageReplacedReceiver.cs | 10 ++++-- src/Android/Services/DeviceActionService.cs | 26 +++++++++++++++ src/App/Abstractions/IDeviceActionService.cs | 3 ++ src/App/App.xaml.cs | 32 +++++++++++++++++++ src/App/Services/MobileStorageService.cs | 3 +- src/App/Utilities/AppHelpers.cs | 27 +++++++++++++++- src/Core/Constants.cs | 1 + 7 files changed, 98 insertions(+), 4 deletions(-) diff --git a/src/Android/Receivers/PackageReplacedReceiver.cs b/src/Android/Receivers/PackageReplacedReceiver.cs index ef0cfba46..2af350320 100644 --- a/src/Android/Receivers/PackageReplacedReceiver.cs +++ b/src/Android/Receivers/PackageReplacedReceiver.cs @@ -1,6 +1,10 @@ using System; using Android.App; using Android.Content; +using Bit.App.Abstractions; +using Bit.App.Utilities; +using Bit.Core.Abstractions; +using Bit.Core.Utilities; namespace Bit.Droid.Receivers { @@ -8,9 +12,11 @@ namespace Bit.Droid.Receivers [IntentFilter(new[] { Intent.ActionMyPackageReplaced })] public class PackageReplacedReceiver : BroadcastReceiver { - public override void OnReceive(Context context, Intent intent) + public override async void OnReceive(Context context, Intent intent) { - System.Diagnostics.Debug.WriteLine("PackageReplacedReceiver OnReceive"); + var storageService = ServiceContainer.Resolve("storageService"); + await AppHelpers.PerformUpdateTasksAsync(ServiceContainer.Resolve("syncService"), + ServiceContainer.Resolve("deviceActionService"), storageService); } } } diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs index 85bf6c988..c38098f40 100644 --- a/src/Android/Services/DeviceActionService.cs +++ b/src/Android/Services/DeviceActionService.cs @@ -293,6 +293,12 @@ namespace Bit.Droid.Services } } + public string GetBuildNumber() + { + return Application.Context.ApplicationContext.PackageManager.GetPackageInfo( + Application.Context.PackageName, 0).VersionCode.ToString(); + } + public bool SupportsFaceId() { return false; @@ -486,6 +492,26 @@ namespace Bit.Droid.Services } } + public bool AutofillAccessibilityServiceRunning() + { + var activity = (MainActivity)CrossCurrentActivity.Current.Activity; + var manager = activity.GetSystemService(Context.ActivityService) as ActivityManager; + var services = manager.GetRunningServices(int.MaxValue); + return services.Any(s => s.Process.ToLowerInvariant().Contains("bitwarden") && + s.Service.ClassName.ToLowerInvariant().Contains("autofill")); + } + + private bool AutofillServiceEnabled() + { + if(Build.VERSION.SdkInt < BuildVersionCodes.O) + { + return false; + } + var activity = (MainActivity)CrossCurrentActivity.Current.Activity; + var afm = (AutofillManager)activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager))); + return afm.IsEnabled && afm.HasEnabledAutofillServices; + } + private bool DeleteDir(Java.IO.File dir) { if(dir != null && dir.IsDirectory) diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs index f07f0e54a..0fdfc396d 100644 --- a/src/App/Abstractions/IDeviceActionService.cs +++ b/src/App/Abstractions/IDeviceActionService.cs @@ -28,5 +28,8 @@ namespace Bit.App.Abstractions void Autofill(CipherView cipher); void CloseAutofill(); void Background(); + bool AutofillAccessibilityServiceRunning(); + bool AutofillServiceEnabled(); + string GetBuildNumber(); } } diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index 8f2e9841c..0d0174ef8 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -106,6 +106,13 @@ namespace Bit.App { // TODO } + else if(message.Command == "resumed") + { + if(Device.RuntimePlatform == Device.iOS) + { + SyncIfNeeded(); + } + } }); } @@ -114,6 +121,15 @@ namespace Bit.App System.Diagnostics.Debug.WriteLine("XF App: OnStart"); await ClearCacheIfNeededAsync(); Prime(); + if(string.IsNullOrWhiteSpace(_appOptions.Uri)) + { + var updated = await AppHelpers.PerformUpdateTasksAsync(_syncService, _deviceActionService, + _storageService); + if(!updated) + { + SyncIfNeeded(); + } + } } protected async override void OnSleep() @@ -129,6 +145,10 @@ namespace Bit.App _messagingService.Send("cancelLockTimer"); await ClearCacheIfNeededAsync(); Prime(); + if(Device.RuntimePlatform == Device.Android) + { + SyncIfNeeded(); + } } private void SetCulture() @@ -264,5 +284,17 @@ namespace Bit.App var mainPageTask = SetMainPageAsync(); ServiceContainer.Resolve("platformUtilsService").Init(); } + + private void SyncIfNeeded() + { + Task.Run(async () => + { + var lastSync = await _syncService.GetLastSyncAsync(); + if(DateTime.UtcNow - lastSync > TimeSpan.FromMinutes(30)) + { + await _syncService.FullSyncAsync(false); + } + }); + } } } diff --git a/src/App/Services/MobileStorageService.cs b/src/App/Services/MobileStorageService.cs index ce36ecf9d..f24a80075 100644 --- a/src/App/Services/MobileStorageService.cs +++ b/src/App/Services/MobileStorageService.cs @@ -22,7 +22,8 @@ namespace Bit.App.Services Constants.AccessibilityAutofillPersistNotificationKey, Constants.LastActiveKey, Constants.PushInitialPromptShownKey, - Constants.LastFileCacheClearKey + Constants.LastFileCacheClearKey, + Constants.LastBuildKey }; public MobileStorageService( diff --git a/src/App/Utilities/AppHelpers.cs b/src/App/Utilities/AppHelpers.cs index e352e6e6e..a914a9ea0 100644 --- a/src/App/Utilities/AppHelpers.cs +++ b/src/App/Utilities/AppHelpers.cs @@ -1,5 +1,7 @@ -using Bit.App.Pages; +using Bit.App.Abstractions; +using Bit.App.Pages; using Bit.App.Resources; +using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Models.View; using Bit.Core.Utilities; @@ -108,5 +110,28 @@ namespace Bit.App.Utilities } return selection; } + + public static async Task PerformUpdateTasksAsync(ISyncService syncService, + IDeviceActionService deviceActionService, IStorageService storageService) + { + var lastSync = await syncService.GetLastSyncAsync(); + var currentBuild = deviceActionService.GetBuildNumber(); + var lastBuild = await storageService.GetAsync(Constants.LastBuildKey); + if(lastBuild == null) + { + // Installed + } + else if(lastBuild != currentBuild) + { + // Updated + var tasks = Task.Run(() => syncService.FullSyncAsync(true)); + } + if(lastBuild != currentBuild) + { + await storageService.SaveAsync(Constants.LastBuildKey, currentBuild); + return true; + } + return false; + } } } diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index 8753c7905..07719e9c7 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -23,6 +23,7 @@ public static string ThemeKey = "theme"; public static string ClearClipboardKey = "clearClipboard"; public static string LastClipboardValueKey = "lastClipboardValue"; + public static string LastBuildKey = "lastBuild"; public const int SelectFileRequestCode = 42; public const int SelectFilePermissionRequestCode = 43; }