diff --git a/src/Android/Services/ClipboardService.cs b/src/Android/Services/ClipboardService.cs index 2abd8df45..7978e8523 100644 --- a/src/Android/Services/ClipboardService.cs +++ b/src/Android/Services/ClipboardService.cs @@ -28,17 +28,25 @@ namespace Bit.Droid.Services public async Task CopyTextAsync(string text, int expiresInMs = -1, bool isSensitive = true) { - // Xamarin.Essentials.Clipboard currently doesn't support the IS_SENSITIVE flag for API 33+ - if ((int)Build.VERSION.SdkInt < 33) + try { - await Clipboard.SetTextAsync(text); - } - else - { - CopyToClipboard(text, isSensitive); - } + // Xamarin.Essentials.Clipboard currently doesn't support the IS_SENSITIVE flag for API 33+ + if ((int)Build.VERSION.SdkInt < 33) + { + await Clipboard.SetTextAsync(text); + } + else + { + CopyToClipboard(text, isSensitive); + } - await ClearClipboardAlarmAsync(expiresInMs); + await ClearClipboardAlarmAsync(expiresInMs); + } + catch (Java.Lang.SecurityException ex) when (ex.Message.Contains("does not belong to")) + { + // #1962 Just ignore, the content is copied either way but there is some app interfiering in the process + // that the OS catches and just throws this exception. + } } public bool IsCopyNotificationHandledByPlatform() diff --git a/src/App/Pages/Vault/ViewPageViewModel.cs b/src/App/Pages/Vault/ViewPageViewModel.cs index 505fdb00b..17f8ef4f6 100644 --- a/src/App/Pages/Vault/ViewPageViewModel.cs +++ b/src/App/Pages/Vault/ViewPageViewModel.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Windows.Input; using Bit.App.Abstractions; using Bit.App.Resources; using Bit.App.Utilities; @@ -11,6 +12,7 @@ using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.Models.View; using Bit.Core.Utilities; +using Xamarin.CommunityToolkit.ObjectModel; using Xamarin.Forms; namespace Bit.App.Pages @@ -28,6 +30,7 @@ namespace Bit.App.Pages private readonly IPasswordRepromptService _passwordRepromptService; private readonly ILocalizeService _localizeService; private readonly IClipboardService _clipboardService; + private readonly ILogger _logger; private CipherView _cipher; private List _fields; @@ -58,10 +61,11 @@ namespace Bit.App.Pages _passwordRepromptService = ServiceContainer.Resolve("passwordRepromptService"); _localizeService = ServiceContainer.Resolve("localizeService"); _clipboardService = ServiceContainer.Resolve("clipboardService"); + _logger = ServiceContainer.Resolve("logger"); - CopyCommand = new Command((id) => CopyAsync(id, null)); - CopyUriCommand = new Command(CopyUri); - CopyFieldCommand = new Command(CopyField); + CopyCommand = new AsyncCommand((id) => CopyAsync(id, null), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false); + CopyUriCommand = new AsyncCommand(uriView => CopyAsync("LoginUri", uriView.Uri), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false); + CopyFieldCommand = new AsyncCommand(field => CopyAsync(field.Type == FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false); LaunchUriCommand = new Command(LaunchUri); TogglePasswordCommand = new Command(TogglePassword); ToggleCardNumberCommand = new Command(ToggleCardNumber); @@ -72,9 +76,9 @@ namespace Bit.App.Pages PageTitle = AppResources.ViewItem; } - public Command CopyCommand { get; set; } - public Command CopyUriCommand { get; set; } - public Command CopyFieldCommand { get; set; } + public ICommand CopyCommand { get; set; } + public ICommand CopyUriCommand { get; set; } + public ICommand CopyFieldCommand { get; set; } public Command LaunchUriCommand { get; set; } public Command TogglePasswordCommand { get; set; } public Command ToggleCardNumberCommand { get; set; } @@ -616,7 +620,7 @@ namespace Bit.App.Pages _attachmentFilename = null; } - private async void CopyAsync(string id, string text = null) + private async Task CopyAsync(string id, string text = null) { if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync()) { @@ -680,16 +684,6 @@ namespace Bit.App.Pages } } - private void CopyUri(LoginUriView uri) - { - CopyAsync("LoginUri", uri.Uri); - } - - private void CopyField(FieldView field) - { - CopyAsync(field.Type == Core.Enums.FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value); - } - private void LaunchUri(LoginUriView uri) { if (uri.CanLaunch && (Page as BaseContentPage).DoOnce())