diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj index 9de256157..47e3863a4 100644 --- a/src/Android/Android.csproj +++ b/src/Android/Android.csproj @@ -112,6 +112,7 @@ + diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index 0f2d5bc61..657613a45 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -16,6 +16,7 @@ using Bit.App.Models; using Bit.Core.Enums; using Android.Nfc; using Bit.App.Utilities; +using System.Threading.Tasks; namespace Bit.Droid { @@ -33,7 +34,10 @@ namespace Bit.Droid private IBroadcasterService _broadcasterService; private IUserService _userService; private IAppIdService _appIdService; + private IStorageService _storageService; + private IStateService _stateService; private PendingIntent _lockAlarmPendingIntent; + private PendingIntent _clearClipboardPendingIntent; private AppOptions _appOptions; private const string HockeyAppId = "d3834185b4a643479047b86c65293d42"; private Java.Util.Regex.Pattern _otpPattern = @@ -44,6 +48,9 @@ namespace Bit.Droid var alarmIntent = new Intent(this, typeof(LockAlarmReceiver)); _lockAlarmPendingIntent = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent); + var clearClipboardIntent = new Intent(this, typeof(ClearClipboardAlarmReceiver)); + _clearClipboardPendingIntent = PendingIntent.GetBroadcast(this, 0, clearClipboardIntent, + PendingIntentFlags.UpdateCurrent); var policy = new StrictMode.ThreadPolicy.Builder().PermitAll().Build(); StrictMode.SetThreadPolicy(policy); @@ -53,6 +60,8 @@ namespace Bit.Droid _broadcasterService = ServiceContainer.Resolve("broadcasterService"); _userService = ServiceContainer.Resolve("userService"); _appIdService = ServiceContainer.Resolve("appIdService"); + _storageService = ServiceContainer.Resolve("storageService"); + _stateService = ServiceContainer.Resolve("stateService"); TabLayoutResource = Resource.Layout.Tabbar; ToolbarResource = Resource.Layout.Toolbar; @@ -105,6 +114,10 @@ namespace Bit.Droid { ExitApp(); } + else if(message.Command == "copiedToClipboard") + { + var task = ClearClipboardAlarmAsync(message.Data as Tuple); + } }); } @@ -293,5 +306,30 @@ namespace Bit.Droid FinishAffinity(); Java.Lang.JavaSystem.Exit(0); } + + private async Task ClearClipboardAlarmAsync(Tuple data) + { + if(data.Item3) + { + return; + } + var clearMs = data.Item2; + if(clearMs == null) + { + var clearSeconds = await _storageService.GetAsync(Constants.ClearClipboardKey); + if(clearSeconds != null) + { + clearMs = clearSeconds.Value * 1000; + } + } + if(clearMs == null) + { + return; + } + await _stateService.SaveAsync(Constants.LastClipboardValueKey, data.Item1); + var triggerMs = Java.Lang.JavaSystem.CurrentTimeMillis() + clearMs.Value; + var alarmManager = GetSystemService(AlarmService) as AlarmManager; + alarmManager.Set(AlarmType.Rtc, triggerMs, _clearClipboardPendingIntent); + } } } diff --git a/src/Android/Receivers/ClearClipboardAlarmReceiver.cs b/src/Android/Receivers/ClearClipboardAlarmReceiver.cs new file mode 100644 index 000000000..d99fb8ff1 --- /dev/null +++ b/src/Android/Receivers/ClearClipboardAlarmReceiver.cs @@ -0,0 +1,23 @@ +using Android.Content; +using Bit.Core; +using Bit.Core.Abstractions; +using Bit.Core.Utilities; + +namespace Bit.Droid.Receivers +{ + [BroadcastReceiver(Name = "com.x8bit.bitwarden.ClearClipboardAlarmReceiver", Exported = false)] + public class ClearClipboardAlarmReceiver : BroadcastReceiver + { + public async override void OnReceive(Context context, Intent intent) + { + var stateService = ServiceContainer.Resolve("stateService"); + var clipboardManager = context.GetSystemService(Context.ClipboardService) as ClipboardManager; + var lastClipboardValue = await stateService.GetAsync(Constants.LastClipboardValueKey); + await stateService.RemoveAsync(Constants.LastClipboardValueKey); + if(lastClipboardValue == clipboardManager.Text) + { + clipboardManager.Text = string.Empty; + } + } + } +} diff --git a/src/Android/Receivers/LockAlarmReceiver.cs b/src/Android/Receivers/LockAlarmReceiver.cs index b4a00e3cc..95979c3bc 100644 --- a/src/Android/Receivers/LockAlarmReceiver.cs +++ b/src/Android/Receivers/LockAlarmReceiver.cs @@ -9,7 +9,6 @@ namespace Bit.Droid.Receivers { public async override void OnReceive(Context context, Intent intent) { - System.Diagnostics.Debug.WriteLine("LockAlarmReceiver OnReceive"); var lockService = ServiceContainer.Resolve("lockService"); await lockService.CheckLockAsync(); } diff --git a/src/App/Services/MobilePlatformUtilsService.cs b/src/App/Services/MobilePlatformUtilsService.cs index f0f6c31da..840f91b63 100644 --- a/src/App/Services/MobilePlatformUtilsService.cs +++ b/src/App/Services/MobilePlatformUtilsService.cs @@ -179,8 +179,12 @@ namespace Bit.App.Services public async Task CopyToClipboardAsync(string text, Dictionary options = null) { var clearMs = options != null && options.ContainsKey("clearMs") ? (int?)options["clearMs"] : null; + var clearing = options != null && options.ContainsKey("clearing") ? (bool)options["clearing"] : false; await Clipboard.SetTextAsync(text); - _messagingService.Send("copiedToClipboard", new Tuple(text, clearMs)); + if(!clearing) + { + _messagingService.Send("copiedToClipboard", new Tuple(text, clearMs, clearing)); + } } public async Task ReadFromClipboardAsync(Dictionary options = null) diff --git a/src/Core/Constants.cs b/src/Core/Constants.cs index ffd42e6ed..8753c7905 100644 --- a/src/Core/Constants.cs +++ b/src/Core/Constants.cs @@ -22,6 +22,7 @@ public static string PushInitialPromptShownKey = "pushInitialPromptShown"; public static string ThemeKey = "theme"; public static string ClearClipboardKey = "clearClipboard"; + public static string LastClipboardValueKey = "lastClipboardValue"; public const int SelectFileRequestCode = 42; public const int SelectFilePermissionRequestCode = 43; }