Enhanced autofill settings (#1150)
* enhanced autofill settings * cleanup
@ -255,13 +255,13 @@ namespace Bit.Droid.Accessibility
|
||||
|
||||
if (!AccessibilityHelpers.OverlayPermitted())
|
||||
{
|
||||
if (!AccessibilityHelpers.IsAutofillTileAdded)
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
|
||||
{
|
||||
// The user has the option of only using the autofill tile and leaving the overlay permission
|
||||
// disabled, so only show this toast if they're using accessibility without overlay permission and
|
||||
// have _not_ added the autofill tile
|
||||
// disabled, so only show this toast if they're using accessibility without overlay permission on
|
||||
// a version of Android without quick-action tile support
|
||||
System.Diagnostics.Debug.WriteLine(">>> Overlay Permission not granted");
|
||||
Toast.MakeText(this, AppResources.AccessibilityOverlayPermissionAlert, ToastLength.Long).Show();
|
||||
Toast.MakeText(this, AppResources.AccessibilityDrawOverPermissionAlert, ToastLength.Long).Show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -161,28 +161,10 @@
|
||||
<None Include="upload-keystore.jks.enc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-hdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_overlay.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_permission.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step1.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\accessibility_step2.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_enable.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\autofill_use.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable-xxhdpi\logo_white_legacy.png" />
|
||||
<AndroidResource Include="Resources\drawable\card.xml" />
|
||||
|
@ -143,13 +143,13 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
|
||||
public static FillResponse BuildFillResponse(Parser parser, List<FilledItem> items, bool locked,
|
||||
FillRequest fillRequest = null)
|
||||
bool inlineAutofillEnabled, FillRequest fillRequest = null)
|
||||
{
|
||||
// Acquire inline presentation specs on Android 11+
|
||||
IList<InlinePresentationSpec> inlinePresentationSpecs = null;
|
||||
var inlinePresentationSpecsCount = 0;
|
||||
var inlineMaxSuggestedCount = 0;
|
||||
if (fillRequest != null && (int)Build.VERSION.SdkInt >= 30)
|
||||
if (inlineAutofillEnabled && fillRequest != null && (int)Build.VERSION.SdkInt >= 30)
|
||||
{
|
||||
var inlineSuggestionsRequest = fillRequest.InlineSuggestionsRequest;
|
||||
inlineMaxSuggestedCount = inlineSuggestionsRequest?.MaxSuggestionCount ?? 0;
|
||||
|
@ -46,6 +46,8 @@ namespace Bit.Droid.Autofill
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var inlineAutofillEnabled = await _storageService.GetAsync<bool?>(Constants.InlineAutofillEnabledKey) ?? true;
|
||||
|
||||
if (_vaultTimeoutService == null)
|
||||
{
|
||||
@ -64,7 +66,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
|
||||
// build response
|
||||
var response = AutofillHelpers.BuildFillResponse(parser, items, locked, request);
|
||||
var response = AutofillHelpers.BuildFillResponse(parser, items, locked, inlineAutofillEnabled, request);
|
||||
callback.OnSuccess(response);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 46 KiB |
@ -378,6 +378,34 @@ namespace Bit.Droid.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableAutofillService()
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var type = Java.Lang.Class.FromType(typeof(AutofillManager));
|
||||
var manager = activity.GetSystemService(type) as AutofillManager;
|
||||
manager.DisableAutofillServices();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public bool AutofillServicesEnabled()
|
||||
{
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
|
||||
{
|
||||
// Android 5-6: Both accessibility & overlay are required or nothing happens
|
||||
return AutofillAccessibilityServiceRunning() && AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
if (Build.VERSION.SdkInt == BuildVersionCodes.N)
|
||||
{
|
||||
// Android 7: Only accessibility is required (overlay is optional when using quick-action tile)
|
||||
return AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
// Android 8+: Either autofill or accessibility is required
|
||||
return AutofillServiceEnabled() || AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
|
||||
public string GetBuildNumber()
|
||||
{
|
||||
return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(
|
||||
|
@ -36,6 +36,8 @@ namespace Bit.App.Abstractions
|
||||
bool AutofillAccessibilityServiceRunning();
|
||||
bool AutofillAccessibilityOverlayPermitted();
|
||||
bool AutofillServiceEnabled();
|
||||
void DisableAutofillService();
|
||||
bool AutofillServicesEnabled();
|
||||
string GetBuildNumber();
|
||||
void OpenAccessibilitySettings();
|
||||
void OpenAccessibilityOverlayPermissionSettings();
|
||||
|
@ -57,8 +57,8 @@
|
||||
<Compile Update="Pages\Settings\ExtensionPage.xaml.cs">
|
||||
<DependentUpon>ExtensionPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\AutofillServicePage.xaml.cs">
|
||||
<DependentUpon>AutofillServicePage.xaml</DependentUpon>
|
||||
<Compile Update="Pages\Settings\AutofillServicesPage.xaml.cs">
|
||||
<DependentUpon>AutofillServicesPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\FolderAddEditPage.xaml.cs">
|
||||
<DependentUpon>FolderAddEditPage.xaml</DependentUpon>
|
||||
@ -72,9 +72,6 @@
|
||||
<Compile Update="Pages\Settings\OptionsPage.xaml.cs">
|
||||
<DependentUpon>OptionsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\AccessibilityServicePage.xaml.cs">
|
||||
<DependentUpon>AccessibilityServicePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Settings\SyncPage.xaml.cs">
|
||||
<DependentUpon>SyncPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -1,109 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.AccessibilityServicePage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:AccessibilityServicePageViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
<pages:AccessibilityServicePageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout Spacing="20"
|
||||
Padding="10, 30"
|
||||
VerticalOptions="FillAndExpand">
|
||||
<Label Text="{u:I18n AutofillAccessibilityDescription}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap" />
|
||||
<StackLayout IsVisible="{Binding Enabled, Converter={StaticResource inverseBool}}"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
Spacing="20">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
|
||||
<Label Text="{u:I18n Status}" />
|
||||
<Label Text="{u:I18n Disabled}"
|
||||
StyleClass="text-danger, text-bold" />
|
||||
</StackLayout>
|
||||
<Image Source="accessibility_step1.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 20, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="98" />
|
||||
<Label Text="{u:I18n BitwardenAutofillServiceStep1}"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap"
|
||||
StyleClass="text-sm" />
|
||||
<Image Source="accessibility_step2.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 10, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="67" />
|
||||
<Label Text="{u:I18n BitwardenAutofillServiceStep2}"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap"
|
||||
StyleClass="text-sm" />
|
||||
</StackLayout>
|
||||
<StackLayout IsVisible="{Binding EnabledWithoutPermission}"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
Spacing="20">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
|
||||
<Label Text="{u:I18n Status}" />
|
||||
<Label Text="{u:I18n Disabled}"
|
||||
StyleClass="text-danger, text-bold" />
|
||||
</StackLayout>
|
||||
<Image Source="accessibility_permission.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 20, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="142" />
|
||||
<Label Text="{u:I18n BitwardenAutofillServiceStep3}"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap"
|
||||
StyleClass="text-sm" />
|
||||
</StackLayout>
|
||||
<StackLayout IsVisible="{Binding EnabledAndPermitted}"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
Spacing="20">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
|
||||
<Label Text="{u:I18n Status}" />
|
||||
<Label Text="{u:I18n Enabled}"
|
||||
StyleClass="text-success, text-bold" />
|
||||
</StackLayout>
|
||||
<Image Source="accessibility_overlay.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 20, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="172" />
|
||||
<Label Text="{u:I18n BitwardenAutofillServiceOverlay}"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap"
|
||||
StyleClass="text-sm" />
|
||||
</StackLayout>
|
||||
<StackLayout Spacing="10">
|
||||
<Button Text="{u:I18n BitwardenAutofillServiceOpenAccessibilitySettings}"
|
||||
Clicked="Settings_Clicked"
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="End"
|
||||
IsVisible="{Binding Enabled, Converter={StaticResource inverseBool}}"></Button>
|
||||
<Button Text="{u:I18n BitwardenAutofillServiceOpenOverlayPermissionSettings}"
|
||||
Clicked="OverlayPermissionSettings_Clicked"
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="End"
|
||||
IsVisible="{Binding Permitted, Converter={StaticResource inverseBool}}"></Button>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
</pages:BaseContentPage>
|
@ -1,66 +0,0 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class AccessibilityServicePageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
|
||||
private bool _enabled;
|
||||
private bool _permitted;
|
||||
|
||||
public AccessibilityServicePageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
PageTitle = AppResources.AutofillAccessibilityService;
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get => _enabled;
|
||||
set => SetProperty(ref _enabled, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(EnabledWithoutPermission),
|
||||
nameof(EnabledAndPermitted)
|
||||
});
|
||||
}
|
||||
|
||||
public bool Permitted
|
||||
{
|
||||
get => _permitted;
|
||||
set => SetProperty(ref _permitted, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(EnabledWithoutPermission),
|
||||
nameof(EnabledAndPermitted)
|
||||
});
|
||||
}
|
||||
|
||||
public bool EnabledWithoutPermission => Enabled && !Permitted;
|
||||
|
||||
public bool EnabledAndPermitted => Enabled && Permitted;
|
||||
|
||||
public void OpenSettings()
|
||||
{
|
||||
_deviceActionService.OpenAccessibilitySettings();
|
||||
}
|
||||
|
||||
public void OpenOverlayPermissionSettings()
|
||||
{
|
||||
_deviceActionService.OpenAccessibilityOverlayPermissionSettings();
|
||||
}
|
||||
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
Enabled = _deviceActionService.AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
|
||||
public void UpdatePermitted()
|
||||
{
|
||||
Permitted = _deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.AutofillServicePage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:AutofillServicePageViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
<pages:AutofillServicePageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout Spacing="20"
|
||||
Padding="10, 30"
|
||||
VerticalOptions="FillAndExpand">
|
||||
<Label Text="{u:I18n AutofillServiceDescription}"
|
||||
VerticalOptions="Start"
|
||||
HorizontalTextAlignment="Center"
|
||||
LineBreakMode="WordWrap" />
|
||||
<StackLayout IsVisible="{Binding Enabled, Converter={StaticResource inverseBool}}"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
Spacing="20">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
|
||||
<Label Text="{u:I18n Status}" />
|
||||
<Label Text="{u:I18n Disabled}"
|
||||
StyleClass="text-danger, text-bold" />
|
||||
</StackLayout>
|
||||
<Image Source="autofill_enable.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 20, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="118" />
|
||||
</StackLayout>
|
||||
<StackLayout IsVisible="{Binding Enabled}"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalOptions="Center"
|
||||
Spacing="20">
|
||||
<StackLayout Orientation="Horizontal" HorizontalOptions="Center">
|
||||
<Label Text="{u:I18n Status}" />
|
||||
<Label Text="{u:I18n Enabled}"
|
||||
StyleClass="text-success, text-bold" />
|
||||
</StackLayout>
|
||||
<Image Source="autofill_use.png"
|
||||
HorizontalOptions="Center"
|
||||
Margin="0, 20, 0, 0"
|
||||
WidthRequest="300"
|
||||
HeightRequest="128" />
|
||||
</StackLayout>
|
||||
<Button Text="{u:I18n BitwardenAutofillServiceOpenAutofillSettings}"
|
||||
Clicked="Settings_Clicked"
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="End"
|
||||
IsVisible="{Binding Enabled, Converter={StaticResource inverseBool}}"></Button>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
</pages:BaseContentPage>
|
@ -1,52 +0,0 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class AutofillServicePage : BaseContentPage
|
||||
{
|
||||
private readonly AutofillServicePageViewModel _vm;
|
||||
private readonly SettingsPage _settingsPage;
|
||||
private DateTime? _timerStarted = null;
|
||||
private TimeSpan _timerMaxLength = TimeSpan.FromMinutes(5);
|
||||
|
||||
public AutofillServicePage(SettingsPage settingsPage)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as AutofillServicePageViewModel;
|
||||
_vm.Page = this;
|
||||
_settingsPage = settingsPage;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
_vm.UpdateEnabled();
|
||||
_timerStarted = DateTime.UtcNow;
|
||||
Device.StartTimer(new TimeSpan(0, 0, 2), () =>
|
||||
{
|
||||
if (_timerStarted == null || (DateTime.UtcNow - _timerStarted) > _timerMaxLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_vm.UpdateEnabled();
|
||||
return true;
|
||||
});
|
||||
base.OnAppearing();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
_timerStarted = null;
|
||||
_settingsPage.BuildList();
|
||||
base.OnDisappearing();
|
||||
}
|
||||
|
||||
private void Settings_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.OpenSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class AutofillServicePageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
|
||||
private bool _enabled;
|
||||
|
||||
public AutofillServicePageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
PageTitle = AppResources.AutofillService;
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get => _enabled;
|
||||
set => SetProperty(ref _enabled, value);
|
||||
}
|
||||
|
||||
public void OpenSettings()
|
||||
{
|
||||
_deviceActionService.OpenAutofillSettings();
|
||||
}
|
||||
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
Enabled = _deviceActionService.AutofillServiceEnabled();
|
||||
}
|
||||
}
|
||||
}
|
133
src/App/Pages/Settings/AutofillServicesPage.xaml
Normal file
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.AutofillServicesPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:AutofillServicesPageViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
<pages:AutofillServicesPageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout Padding="0" Spacing="20">
|
||||
<StackLayout
|
||||
StyleClass="box"
|
||||
IsVisible="{Binding AutofillServiceVisible}">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Label
|
||||
Text="{u:I18n AutofillService}"
|
||||
StyleClass="box-label, box-label-regular"
|
||||
HorizontalOptions="StartAndExpand" />
|
||||
<RelativeLayout HorizontalOptions="End">
|
||||
<Switch
|
||||
x:Name="AutofillServiceSwitch"
|
||||
IsToggled="{Binding AutofillServiceToggled}"
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="End" />
|
||||
<Button
|
||||
Clicked="ToggleAutofillService"
|
||||
BackgroundColor="Transparent"
|
||||
RelativeLayout.XConstraint="0"
|
||||
RelativeLayout.YConstraint="0"
|
||||
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AutofillServiceSwitch, Property=Width}"
|
||||
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AutofillServiceSwitch, Property=Height}" />
|
||||
</RelativeLayout>
|
||||
</StackLayout>
|
||||
<Label
|
||||
Text="{u:I18n AutofillServiceDescription}"
|
||||
StyleClass="box-footer-label, box-footer-label-switch" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
StyleClass="box"
|
||||
IsVisible="{Binding InlineAutofillVisible}">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Label
|
||||
Text="{u:I18n InlineAutofill}"
|
||||
StyleClass="box-label, box-label-regular"
|
||||
IsEnabled="{Binding InlineAutofillEnabled}"
|
||||
HorizontalOptions="StartAndExpand" />
|
||||
<RelativeLayout HorizontalOptions="End">
|
||||
<Switch
|
||||
x:Name="InlineAutofillSwitch"
|
||||
IsEnabled="{Binding InlineAutofillEnabled}"
|
||||
IsToggled="{Binding InlineAutofillToggled}"
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="End" />
|
||||
<Button
|
||||
Clicked="ToggleInlineAutofill"
|
||||
IsEnabled="{Binding InlineAutofillEnabled}"
|
||||
BackgroundColor="Transparent"
|
||||
RelativeLayout.XConstraint="0"
|
||||
RelativeLayout.YConstraint="0"
|
||||
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=InlineAutofillSwitch, Property=Width}"
|
||||
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=InlineAutofillSwitch, Property=Height}" />
|
||||
</RelativeLayout>
|
||||
</StackLayout>
|
||||
<Label
|
||||
Text="{u:I18n InlineAutofillDescription}"
|
||||
StyleClass="box-footer-label, box-footer-label-switch"
|
||||
IsEnabled="{Binding InlineAutofillEnabled}"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Label
|
||||
Text="{u:I18n Accessibility}"
|
||||
StyleClass="box-label, box-label-regular"
|
||||
HorizontalOptions="StartAndExpand" />
|
||||
<RelativeLayout HorizontalOptions="End">
|
||||
<Switch
|
||||
x:Name="AccessibilitySwitch"
|
||||
IsToggled="{Binding AccessibilityToggled}"
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="End" />
|
||||
<Button
|
||||
Clicked="ToggleAccessibility"
|
||||
BackgroundColor="Transparent"
|
||||
RelativeLayout.XConstraint="0"
|
||||
RelativeLayout.YConstraint="0"
|
||||
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AccessibilitySwitch, Property=Width}"
|
||||
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=AccessibilitySwitch, Property=Height}" />
|
||||
</RelativeLayout>
|
||||
</StackLayout>
|
||||
<Label
|
||||
Text="{Binding AccessibilityDescriptionLabel}"
|
||||
StyleClass="box-footer-label, box-footer-label-switch" />
|
||||
</StackLayout>
|
||||
<StackLayout
|
||||
StyleClass="box"
|
||||
IsVisible="{Binding DrawOverVisible}">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Label
|
||||
Text="{u:I18n DrawOver}"
|
||||
StyleClass="box-label, box-label-regular"
|
||||
IsEnabled="{Binding DrawOverEnabled}"
|
||||
HorizontalOptions="StartAndExpand" />
|
||||
<RelativeLayout HorizontalOptions="End">
|
||||
<Switch
|
||||
x:Name="DrawOverSwitch"
|
||||
IsEnabled="{Binding DrawOverEnabled}"
|
||||
IsToggled="{Binding DrawOverToggled}"
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="End" />
|
||||
<Button
|
||||
Clicked="ToggleDrawOver"
|
||||
IsEnabled="{Binding DrawOverEnabled}"
|
||||
BackgroundColor="Transparent"
|
||||
RelativeLayout.XConstraint="0"
|
||||
RelativeLayout.YConstraint="0"
|
||||
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=DrawOverSwitch, Property=Width}"
|
||||
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=DrawOverSwitch, Property=Height}" />
|
||||
</RelativeLayout>
|
||||
</StackLayout>
|
||||
<Label
|
||||
Text="{Binding DrawOverDescriptionLabel}"
|
||||
StyleClass="box-footer-label, box-footer-label-switch"
|
||||
IsEnabled="{Binding InlineAutofillEnabled}"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
</pages:BaseContentPage>
|
@ -3,34 +3,33 @@ using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class AccessibilityServicePage : BaseContentPage
|
||||
public partial class AutofillServicesPage : BaseContentPage
|
||||
{
|
||||
private readonly AccessibilityServicePageViewModel _vm;
|
||||
private readonly AutofillServicesPageViewModel _vm;
|
||||
private readonly SettingsPage _settingsPage;
|
||||
private DateTime? _timerStarted = null;
|
||||
private TimeSpan _timerMaxLength = TimeSpan.FromMinutes(5);
|
||||
|
||||
public AccessibilityServicePage(SettingsPage settingsPage)
|
||||
public AutofillServicesPage(SettingsPage settingsPage)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as AccessibilityServicePageViewModel;
|
||||
_vm = BindingContext as AutofillServicesPageViewModel;
|
||||
_vm.Page = this;
|
||||
_settingsPage = settingsPage;
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
await _vm.InitAsync();
|
||||
_vm.UpdateEnabled();
|
||||
_vm.UpdatePermitted();
|
||||
_timerStarted = DateTime.UtcNow;
|
||||
Device.StartTimer(new TimeSpan(0, 0, 3), () =>
|
||||
Device.StartTimer(new TimeSpan(0, 0, 0, 0, 500), () =>
|
||||
{
|
||||
if (_timerStarted == null || (DateTime.UtcNow - _timerStarted) > _timerMaxLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_vm.UpdateEnabled();
|
||||
_vm.UpdatePermitted();
|
||||
return true;
|
||||
});
|
||||
base.OnAppearing();
|
||||
@ -43,19 +42,32 @@ namespace Bit.App.Pages
|
||||
base.OnDisappearing();
|
||||
}
|
||||
|
||||
private void Settings_Clicked(object sender, EventArgs e)
|
||||
private void ToggleAutofillService(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.OpenSettings();
|
||||
_vm.ToggleAutofillService();
|
||||
}
|
||||
}
|
||||
|
||||
private void OverlayPermissionSettings_Clicked(object sender, EventArgs e)
|
||||
|
||||
private void ToggleInlineAutofill(object sender, EventArgs e)
|
||||
{
|
||||
_vm.ToggleInlineAutofill();
|
||||
}
|
||||
|
||||
private void ToggleAccessibility(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.OpenOverlayPermissionSettings();
|
||||
_vm.ToggleAccessibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleDrawOver(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.ToggleDrawOver();
|
||||
}
|
||||
}
|
||||
}
|
201
src/App/Pages/Settings/AutofillServicesPageViewModel.cs
Normal file
@ -0,0 +1,201 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class AutofillServicesPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IStorageService _storageService;
|
||||
private readonly MobileI18nService _i18nService;
|
||||
|
||||
private bool _autofillServiceToggled;
|
||||
private bool _inlineAutofillToggled;
|
||||
private bool _accessibilityToggled;
|
||||
private bool _drawOverToggled;
|
||||
private bool _inited;
|
||||
|
||||
public AutofillServicesPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService;
|
||||
PageTitle = AppResources.AutofillServices;
|
||||
}
|
||||
|
||||
#region Autofill Service
|
||||
|
||||
public bool AutofillServiceVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 26;
|
||||
}
|
||||
|
||||
public bool AutofillServiceToggled
|
||||
{
|
||||
get => _autofillServiceToggled;
|
||||
set => SetProperty(ref _autofillServiceToggled, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(InlineAutofillEnabled)
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Inline Autofill
|
||||
|
||||
public bool InlineAutofillVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 30;
|
||||
}
|
||||
|
||||
public bool InlineAutofillEnabled
|
||||
{
|
||||
get => AutofillServiceToggled;
|
||||
}
|
||||
|
||||
public bool InlineAutofillToggled
|
||||
{
|
||||
get => _inlineAutofillToggled;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _inlineAutofillToggled, value))
|
||||
{
|
||||
var task = UpdateInlineAutofillToggledAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accessibility
|
||||
|
||||
public string AccessibilityDescriptionLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_deviceActionService.SystemMajorVersion() <= 22)
|
||||
{
|
||||
// Android 5
|
||||
return _i18nService.T("AccessibilityDescription");
|
||||
}
|
||||
if (_deviceActionService.SystemMajorVersion() == 23)
|
||||
{
|
||||
// Android 6
|
||||
return _i18nService.T("AccessibilityDescription2");
|
||||
}
|
||||
if (_deviceActionService.SystemMajorVersion() == 24 || _deviceActionService.SystemMajorVersion() == 25)
|
||||
{
|
||||
// Android 7
|
||||
return _i18nService.T("AccessibilityDescription3");
|
||||
}
|
||||
// Android 8+
|
||||
return _i18nService.T("AccessibilityDescription4");
|
||||
}
|
||||
}
|
||||
|
||||
public bool AccessibilityToggled
|
||||
{
|
||||
get => _accessibilityToggled;
|
||||
set => SetProperty(ref _accessibilityToggled, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(DrawOverEnabled)
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Draw-Over
|
||||
|
||||
public bool DrawOverVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 23;
|
||||
}
|
||||
|
||||
public string DrawOverDescriptionLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_deviceActionService.SystemMajorVersion() <= 23)
|
||||
{
|
||||
// Android 6
|
||||
return _i18nService.T("DrawOverDescription");
|
||||
}
|
||||
if (_deviceActionService.SystemMajorVersion() == 24 || _deviceActionService.SystemMajorVersion() == 25)
|
||||
{
|
||||
// Android 7
|
||||
return _i18nService.T("DrawOverDescription2");
|
||||
}
|
||||
// Android 8+
|
||||
return _i18nService.T("DrawOverDescription3");
|
||||
}
|
||||
}
|
||||
|
||||
public bool DrawOverEnabled
|
||||
{
|
||||
get => AccessibilityToggled;
|
||||
}
|
||||
|
||||
public bool DrawOverToggled
|
||||
{
|
||||
get => _drawOverToggled;
|
||||
set => SetProperty(ref _drawOverToggled, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
InlineAutofillToggled = await _storageService.GetAsync<bool?>(Constants.InlineAutofillEnabledKey) ?? true;
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
public void ToggleAutofillService()
|
||||
{
|
||||
if (!AutofillServiceToggled)
|
||||
{
|
||||
_deviceActionService.OpenAutofillSettings();
|
||||
}
|
||||
else
|
||||
{
|
||||
_deviceActionService.DisableAutofillService();
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleInlineAutofill()
|
||||
{
|
||||
InlineAutofillToggled = !InlineAutofillToggled;
|
||||
}
|
||||
|
||||
public void ToggleAccessibility()
|
||||
{
|
||||
_deviceActionService.OpenAccessibilitySettings();
|
||||
}
|
||||
|
||||
public void ToggleDrawOver()
|
||||
{
|
||||
_deviceActionService.OpenAccessibilityOverlayPermissionSettings();
|
||||
}
|
||||
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
AutofillServiceToggled = _deviceActionService.AutofillServiceEnabled();
|
||||
AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning();
|
||||
DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
|
||||
private async Task UpdateInlineAutofillToggledAsync()
|
||||
{
|
||||
if (_inited)
|
||||
{
|
||||
await _storageService.SaveAsync(Constants.InlineAutofillEnabledKey, InlineAutofillToggled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -57,13 +57,9 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await Navigation.PushModalAsync(new NavigationPage(new SyncPage()));
|
||||
}
|
||||
else if (item.Name == AppResources.AutofillAccessibilityService)
|
||||
else if (item.Name == AppResources.AutofillServices)
|
||||
{
|
||||
await Navigation.PushModalAsync(new NavigationPage(new AccessibilityServicePage(this)));
|
||||
}
|
||||
else if (item.Name == AppResources.AutofillService)
|
||||
{
|
||||
await Navigation.PushModalAsync(new NavigationPage(new AutofillServicePage(this)));
|
||||
await Navigation.PushModalAsync(new NavigationPage(new AutofillServicesPage(this)));
|
||||
}
|
||||
else if (item.Name == AppResources.PasswordAutofill)
|
||||
{
|
||||
|
@ -326,22 +326,10 @@ namespace Bit.App.Pages
|
||||
var autofillItems = new List<SettingsPageListItem>();
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
if (_deviceActionService.SupportsAutofillService())
|
||||
{
|
||||
autofillItems.Add(new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.AutofillService,
|
||||
SubLabel = _deviceActionService.AutofillServiceEnabled() ?
|
||||
AppResources.Enabled : AppResources.Disabled
|
||||
});
|
||||
}
|
||||
|
||||
var accessibilityEnabled = _deviceActionService.AutofillAccessibilityServiceRunning() &&
|
||||
_deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
autofillItems.Add(new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.AutofillAccessibilityService,
|
||||
SubLabel = accessibilityEnabled ?
|
||||
Name = AppResources.AutofillServices,
|
||||
SubLabel = _deviceActionService.AutofillServicesEnabled() ?
|
||||
AppResources.Enabled : AppResources.Disabled
|
||||
});
|
||||
}
|
||||
|
78
src/App/Resources/AppResources.Designer.cs
generated
@ -3074,5 +3074,83 @@ namespace Bit.App.Resources {
|
||||
return ResourceManager.GetString("PrivacyPolicy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AccessibilityDrawOverPermissionAlert {
|
||||
get {
|
||||
return ResourceManager.GetString("AccessibilityDrawOverPermissionAlert", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AutofillServices {
|
||||
get {
|
||||
return ResourceManager.GetString("AutofillServices", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string InlineAutofill {
|
||||
get {
|
||||
return ResourceManager.GetString("InlineAutofill", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string InlineAutofillDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("InlineAutofillDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Accessibility {
|
||||
get {
|
||||
return ResourceManager.GetString("Accessibility", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AccessibilityDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("AccessibilityDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AccessibilityDescription2 {
|
||||
get {
|
||||
return ResourceManager.GetString("AccessibilityDescription2", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AccessibilityDescription3 {
|
||||
get {
|
||||
return ResourceManager.GetString("AccessibilityDescription3", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string AccessibilityDescription4 {
|
||||
get {
|
||||
return ResourceManager.GetString("AccessibilityDescription4", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string DrawOver {
|
||||
get {
|
||||
return ResourceManager.GetString("DrawOver", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string DrawOverDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("DrawOverDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string DrawOverDescription2 {
|
||||
get {
|
||||
return ResourceManager.GetString("DrawOverDescription2", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string DrawOverDescription3 {
|
||||
get {
|
||||
return ResourceManager.GetString("DrawOverDescription3", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1744,4 +1744,43 @@
|
||||
<data name="PrivacyPolicy" xml:space="preserve">
|
||||
<value>Privacy Policy</value>
|
||||
</data>
|
||||
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden needs attention - Enable "Draw-Over" in "Auto-fill Services" from Bitwarden Settings</value>
|
||||
</data>
|
||||
<data name="AutofillServices" xml:space="preserve">
|
||||
<value>Auto-fill Services</value>
|
||||
</data>
|
||||
<data name="InlineAutofill" xml:space="preserve">
|
||||
<value>Use Inline Autofill</value>
|
||||
</data>
|
||||
<data name="InlineAutofillDescription" xml:space="preserve">
|
||||
<value>Use inline autofill if your selected IME (keyboard) supports it. If your configuration is not supported (or this option is disabled), the default Autofill overlay will be used.</value>
|
||||
</data>
|
||||
<data name="Accessibility" xml:space="preserve">
|
||||
<value>Use Accessibility</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. When enabled, we'll display a popup when login fields are selected.</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription2" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. (Requires Draw-Over to be enabled as well)</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription3" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to use the Autofill Quick-Action Tile, and/or show a popup using Draw-Over (if enabled).</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription4" xml:space="preserve">
|
||||
<value>Required to use the Autofill Quick-Action Tile, or to augment the Autofill Service by using Draw-Over (if enabled).</value>
|
||||
</data>
|
||||
<data name="DrawOver" xml:space="preserve">
|
||||
<value>Use Draw-Over</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription" xml:space="preserve">
|
||||
<value>When enabled, allows the Bitwarden Accessibility Service to display a popup when login fields are selected.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription2" xml:space="preserve">
|
||||
<value>If enabled, the Bitwarden Accessibility Service will display a popup when login fields are selected to assist with auto-filling your logins.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription3" xml:space="preserve">
|
||||
<value>If enabled, accessibility will show a popup to augment the Autofill Service for older apps that don't support the Android Autofill Framework.</value>
|
||||
</data>
|
||||
</root>
|
@ -35,6 +35,7 @@ namespace Bit.App.Services
|
||||
Constants.iOSAutoFillClearCiphersCacheKey,
|
||||
Constants.iOSExtensionClearCiphersCacheKey,
|
||||
Constants.EnvironmentUrlsKey,
|
||||
Constants.InlineAutofillEnabledKey,
|
||||
};
|
||||
|
||||
private readonly HashSet<string> _migrateToPreferences = new HashSet<string>
|
||||
|
@ -36,6 +36,7 @@
|
||||
public static string TriedV1Resync = "triedV1Resync";
|
||||
public static string EventCollectionKey = "eventCollection";
|
||||
public static string PreviousPageKey = "previousPage";
|
||||
public static string InlineAutofillEnabledKey = "inlineAutofillEnabled";
|
||||
public const int SelectFileRequestCode = 42;
|
||||
public const int SelectFilePermissionRequestCode = 43;
|
||||
public const int SaveFileRequestCode = 44;
|
||||
|
@ -392,6 +392,16 @@ namespace Bit.iOS.Core.Services
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void DisableAutofillService()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool AutofillServicesEnabled()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public string GetBuildNumber()
|
||||
{
|
||||
return NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString();
|
||||
|