diff --git a/src/Android/Services/DeviceActionService.cs b/src/Android/Services/DeviceActionService.cs
index 3f649ad96..3a22506ae 100644
--- a/src/Android/Services/DeviceActionService.cs
+++ b/src/Android/Services/DeviceActionService.cs
@@ -512,6 +512,35 @@ namespace Bit.Droid.Services
return afm.IsEnabled && afm.HasEnabledAutofillServices;
}
+ public void OpenAccessibilitySettings()
+ {
+ var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
+ var intent = new Intent(Settings.ActionAccessibilitySettings);
+ activity.StartActivity(intent);
+ }
+
+ public void OpenAutofillSettings()
+ {
+ var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
+ try
+ {
+ var intent = new Intent(Settings.ActionRequestSetAutofillService);
+ intent.SetData(Android.Net.Uri.Parse("package:com.x8bit.bitwarden"));
+ activity.StartActivity(intent);
+ }
+ catch(ActivityNotFoundException)
+ {
+ var alertBuilder = new AlertDialog.Builder(activity);
+ alertBuilder.SetMessage(AppResources.BitwardenAutofillGoToSettings);
+ alertBuilder.SetCancelable(true);
+ alertBuilder.SetPositiveButton(AppResources.Ok, (sender, args) =>
+ {
+ (sender as AlertDialog)?.Cancel();
+ });
+ alertBuilder.Create().Show();
+ }
+ }
+
private bool DeleteDir(Java.IO.File dir)
{
if(dir != null && dir.IsDirectory)
diff --git a/src/App/Abstractions/IDeviceActionService.cs b/src/App/Abstractions/IDeviceActionService.cs
index 0fdfc396d..6e0126ee5 100644
--- a/src/App/Abstractions/IDeviceActionService.cs
+++ b/src/App/Abstractions/IDeviceActionService.cs
@@ -31,5 +31,7 @@ namespace Bit.App.Abstractions
bool AutofillAccessibilityServiceRunning();
bool AutofillServiceEnabled();
string GetBuildNumber();
+ void OpenAccessibilitySettings();
+ void OpenAutofillSettings();
}
}
diff --git a/src/App/App.csproj b/src/App/App.csproj
index 2e27b8e4a..2b003fcf9 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -60,6 +60,9 @@
OptionsPage.xaml
+
+ AccessibilityServicePage.xaml
+
SyncPage.xaml
diff --git a/src/App/Pages/Settings/AccessibilityServicePage.xaml b/src/App/Pages/Settings/AccessibilityServicePage.xaml
new file mode 100644
index 000000000..752dd8a18
--- /dev/null
+++ b/src/App/Pages/Settings/AccessibilityServicePage.xaml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Settings/AccessibilityServicePage.xaml.cs b/src/App/Pages/Settings/AccessibilityServicePage.xaml.cs
new file mode 100644
index 000000000..1a921ffbd
--- /dev/null
+++ b/src/App/Pages/Settings/AccessibilityServicePage.xaml.cs
@@ -0,0 +1,52 @@
+using System;
+using Xamarin.Forms;
+
+namespace Bit.App.Pages
+{
+ public partial class AccessibilityServicePage : BaseContentPage
+ {
+ private readonly AccessibilityServicePageViewModel _vm;
+ private readonly SettingsPage _settingsPage;
+ private DateTime? _timerStarted = null;
+ private TimeSpan _timerMaxLength = TimeSpan.FromMinutes(5);
+
+ public AccessibilityServicePage(SettingsPage settingsPage)
+ {
+ InitializeComponent();
+ _vm = BindingContext as AccessibilityServicePageViewModel;
+ _vm.Page = this;
+ _settingsPage = settingsPage;
+ }
+
+ protected override void OnAppearing()
+ {
+ _vm.UpdateEnabled();
+ _timerStarted = DateTime.UtcNow;
+ Device.StartTimer(new TimeSpan(0, 0, 3), () =>
+ {
+ 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();
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/AccessibilityServicePageViewModel.cs b/src/App/Pages/Settings/AccessibilityServicePageViewModel.cs
new file mode 100644
index 000000000..1bc5f5bdd
--- /dev/null
+++ b/src/App/Pages/Settings/AccessibilityServicePageViewModel.cs
@@ -0,0 +1,38 @@
+using Bit.App.Abstractions;
+using Bit.App.Resources;
+using Bit.Core.Abstractions;
+using Bit.Core.Utilities;
+
+namespace Bit.App.Pages
+{
+ public class AccessibilityServicePageViewModel : BaseViewModel
+ {
+ private readonly IDeviceActionService _deviceActionService;
+ private readonly IPlatformUtilsService _platformUtilsService;
+
+ private bool _enabled;
+
+ public AccessibilityServicePageViewModel()
+ {
+ _deviceActionService = ServiceContainer.Resolve("deviceActionService");
+ _platformUtilsService = ServiceContainer.Resolve("platformUtilsService");
+ PageTitle = AppResources.AutofillAccessibilityService;
+ }
+
+ public bool Enabled
+ {
+ get => _enabled;
+ set => SetProperty(ref _enabled, value);
+ }
+
+ public void OpenSettings()
+ {
+ _deviceActionService.OpenAccessibilitySettings();
+ }
+
+ public void UpdateEnabled()
+ {
+ Enabled = _deviceActionService.AutofillAccessibilityServiceRunning();
+ }
+ }
+}
diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs b/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
index 3295ed59d..a0ed4737f 100644
--- a/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
+++ b/src/App/Pages/Settings/SettingsPage/SettingsPage.xaml.cs
@@ -26,6 +26,11 @@ namespace Bit.App.Pages
await _vm.InitAsync();
}
+ public void BuildList()
+ {
+ _vm.BuildList();
+ }
+
protected override bool OnBackButtonPressed()
{
if(Device.RuntimePlatform == Device.Android && _tabsPage != null)
@@ -54,7 +59,7 @@ namespace Bit.App.Pages
}
else if(item.Name == AppResources.AutofillAccessibilityService)
{
- // await Navigation.PushModalAsync(new NavigationPage(new OptionsPage()));
+ await Navigation.PushModalAsync(new NavigationPage(new AccessibilityServicePage(this)));
}
else if(item.Name == AppResources.AutofillService)
{
diff --git a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs
index 91869618b..2cadfd63f 100644
--- a/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs
+++ b/src/App/Pages/Settings/SettingsPage/SettingsPageViewModel.cs
@@ -270,7 +270,7 @@ namespace Bit.App.Pages
BuildList();
}
- private void BuildList()
+ public void BuildList()
{
var doUpper = Device.RuntimePlatform != Device.Android;
var autofillItems = new List();