diff --git a/src/keepass2android/EntryActivity.cs b/src/keepass2android/EntryActivity.cs index bc745081..ecc10dd6 100644 --- a/src/keepass2android/EntryActivity.cs +++ b/src/keepass2android/EntryActivity.cs @@ -982,7 +982,7 @@ namespace keepass2android popupKey, container, anchor); - popupItems.Add(new CopyToClipboardPopupMenuIcon(this, _stringViews[fieldKey])); + popupItems.Add(new CopyToClipboardPopupMenuIcon(this, _stringViews[fieldKey], isProtected)); if (isProtected) { var valueView = container.FindViewById(fieldKey == PwDefs.PasswordField ? Resource.Id.entry_password : Resource.Id.entry_extra); diff --git a/src/keepass2android/EntryActivityClasses/CopyToClipboardPopupMenuIcon.cs b/src/keepass2android/EntryActivityClasses/CopyToClipboardPopupMenuIcon.cs index 937a984b..d8a226cf 100644 --- a/src/keepass2android/EntryActivityClasses/CopyToClipboardPopupMenuIcon.cs +++ b/src/keepass2android/EntryActivityClasses/CopyToClipboardPopupMenuIcon.cs @@ -10,12 +10,13 @@ namespace keepass2android { private readonly Context _context; private readonly IStringView _stringView; + private readonly bool _isProtected; - public CopyToClipboardPopupMenuIcon(Context context, IStringView stringView) + public CopyToClipboardPopupMenuIcon(Context context, IStringView stringView, bool isProtected) { _context = context; _stringView = stringView; - + _isProtected = isProtected; } public Drawable Icon @@ -33,7 +34,7 @@ namespace keepass2android public void HandleClick() { - CopyToClipboardService.CopyValueToClipboardWithTimeout(_context, _stringView.Text); + CopyToClipboardService.CopyValueToClipboardWithTimeout(_context, _stringView.Text, _isProtected); } } } \ No newline at end of file diff --git a/src/keepass2android/Utils/Util.cs b/src/keepass2android/Utils/Util.cs index 1624b58c..0fc0a7de 100644 --- a/src/keepass2android/Utils/Util.cs +++ b/src/keepass2android/Utils/Util.cs @@ -200,9 +200,19 @@ namespace keepass2android return ""; } - public static void CopyToClipboard(Context context, String text) { + public static void CopyToClipboard(Context context, String text, bool isProtected) { Android.Content.ClipboardManager clipboardManager = (ClipboardManager)context.GetSystemService(Context.ClipboardService); ClipData clipData = Android.Content.ClipData.NewPlainText("KP2A", text); + if (isProtected) + { + //ClipDescription.Extras is only available since 24 + if ((int) Build.VERSION.SdkInt >= 24) + { + var extras = clipData.Description.Extras ?? new Android.OS.PersistableBundle(); + extras.PutBoolean("android.content.extra.IS_SENSITIVE", true); + clipData.Description.Extras = extras; + } + } clipboardManager.PrimaryClip = clipData; if (text == "") { diff --git a/src/keepass2android/services/CopyToClipboardService.cs b/src/keepass2android/services/CopyToClipboardService.cs index 66925fb0..4edcaa45 100644 --- a/src/keepass2android/services/CopyToClipboardService.cs +++ b/src/keepass2android/services/CopyToClipboardService.cs @@ -262,11 +262,12 @@ namespace keepass2android public const int NotifyCombined = 5; public const int NotifyTotp = 6; - static public void CopyValueToClipboardWithTimeout(Context ctx, string text) + static public void CopyValueToClipboardWithTimeout(Context ctx, string text, bool isProtected) { Intent i = new Intent(ctx, typeof(CopyToClipboardService)); i.SetAction(Intents.CopyStringToClipboard); i.PutExtra(_stringtocopy, text); + i.PutExtra(_stringisprotected, isProtected); ctx.StartService(i); } @@ -377,7 +378,7 @@ namespace keepass2android if (intent.Action == Intents.CopyStringToClipboard) { - TimeoutCopyToClipboard(intent.GetStringExtra(_stringtocopy)); + TimeoutCopyToClipboard(intent.GetStringExtra(_stringtocopy), intent.GetBooleanExtra(_stringisprotected, false)); } if (intent.Action == Intents.ActivateKeyboard) { @@ -673,9 +674,9 @@ namespace keepass2android private readonly Timer _timer = new Timer(); - internal void TimeoutCopyToClipboard(String text) + internal void TimeoutCopyToClipboard(String text, bool isProtected) { - Util.CopyToClipboard(this, text); + Util.CopyToClipboard(this, text, isProtected); ISharedPreferences prefs = PreferenceManager.GetDefaultSharedPreferences(this); String sClipClear = prefs.GetString(GetString(Resource.String.clipboard_timeout_key), GetString(Resource.String.clipboard_timeout_default)); @@ -711,7 +712,7 @@ namespace keepass2android DoPostClear(); if (currentClip.Equals(_clearText)) { - Util.CopyToClipboard(_service, ""); + Util.CopyToClipboard(_service, "", false); DoPostWarn(); } } @@ -747,6 +748,7 @@ namespace keepass2android readonly Handler _uiThreadCallback = new Handler(); private ClearClipboardTask _clearClipboardTask; private const string _stringtocopy = "StringToCopy"; + private const string _stringisprotected = "StringIsProtected"; @@ -942,7 +944,7 @@ namespace keepass2android String username = App.Kp2a.LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.UserNameField); if (username.Length > 0) { - CopyToClipboardService.CopyValueToClipboardWithTimeout(context, username); + CopyToClipboardService.CopyValueToClipboardWithTimeout(context, username, false); } context.SendBroadcast(new Intent(Intent.ActionCloseSystemDialogs)); //close notification drawer } @@ -951,7 +953,7 @@ namespace keepass2android String password = App.Kp2a.LastOpenedEntry.OutputStrings.ReadSafe(PwDefs.PasswordField); if (password.Length > 0) { - CopyToClipboardService.CopyValueToClipboardWithTimeout(context, password); + CopyToClipboardService.CopyValueToClipboardWithTimeout(context, password, true); } context.SendBroadcast(new Intent(Intent.ActionCloseSystemDialogs)); //close notification drawer } @@ -960,7 +962,7 @@ namespace keepass2android String totp = App.Kp2a.LastOpenedEntry.OutputStrings.ReadSafe(UpdateTotpTimerTask.TotpKey); if (totp.Length > 0) { - CopyToClipboardService.CopyValueToClipboardWithTimeout(context, totp); + CopyToClipboardService.CopyValueToClipboardWithTimeout(context, totp, true); } context.SendBroadcast(new Intent(Intent.ActionCloseSystemDialogs)); //close notification drawer }