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;
}