mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
add tools page for autofill service
This commit is contained in:
parent
9bbddd6aeb
commit
783c4d104c
17 changed files with 222 additions and 5 deletions
|
@ -1,4 +1,5 @@
|
||||||
using Android.App;
|
using Android.App;
|
||||||
|
using Android.Views.Autofill;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AndroidApp = Android.App.Application;
|
using AndroidApp = Android.App.Application;
|
||||||
|
@ -13,14 +14,27 @@ namespace Bit.Android.Services
|
||||||
public string Build => AndroidApp.Context.ApplicationContext.PackageManager
|
public string Build => AndroidApp.Context.ApplicationContext.PackageManager
|
||||||
.GetPackageInfo(AndroidApp.Context.PackageName, 0).VersionCode.ToString();
|
.GetPackageInfo(AndroidApp.Context.PackageName, 0).VersionCode.ToString();
|
||||||
|
|
||||||
public bool AutofillServiceEnabled => AutofillRunning();
|
public bool AutofillAccessibilityServiceEnabled => AutofillAccessibilityRunning();
|
||||||
|
public bool AutofillServiceEnabled => AutofillEnabled();
|
||||||
|
|
||||||
private bool AutofillRunning()
|
private bool AutofillAccessibilityRunning()
|
||||||
{
|
{
|
||||||
var manager = ((ActivityManager)Xamarin.Forms.Forms.Context.GetSystemService("activity"));
|
var manager = ((ActivityManager)Xamarin.Forms.Forms.Context.GetSystemService("activity"));
|
||||||
var services = manager.GetRunningServices(int.MaxValue);
|
var services = manager.GetRunningServices(int.MaxValue);
|
||||||
return services.Any(s => s.Process.ToLowerInvariant().Contains("bitwarden") &&
|
return services.Any(s => s.Process.ToLowerInvariant().Contains("bitwarden") &&
|
||||||
s.Service.ClassName.ToLowerInvariant().Contains("autofill"));
|
s.Service.ClassName.ToLowerInvariant().Contains("autofill"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool AutofillEnabled()
|
||||||
|
{
|
||||||
|
if(global::Android.OS.Build.VERSION.SdkInt < global::Android.OS.BuildVersionCodes.O)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activity = (MainActivity)Xamarin.Forms.Forms.Context;
|
||||||
|
var afm = (AutofillManager)activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager)));
|
||||||
|
return afm.IsEnabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,5 +407,13 @@ namespace Bit.Android.Services
|
||||||
ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, new string[] { permission },
|
ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, new string[] { permission },
|
||||||
Constants.SelectFilePermissionRequestCode);
|
Constants.SelectFilePermissionRequestCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenAutofillSettings()
|
||||||
|
{
|
||||||
|
var activity = (MainActivity)Forms.Context;
|
||||||
|
var intent = new Intent(Settings.ActionRequestSetAutofillService);
|
||||||
|
intent.SetData(global::Android.Net.Uri.Parse("package:com.x8bit.bitwarden"));
|
||||||
|
activity.StartActivity(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
|
using Android.Views.Autofill;
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
|
|
||||||
namespace Bit.Android.Services
|
namespace Bit.Android.Services
|
||||||
|
@ -44,5 +45,18 @@ namespace Bit.Android.Services
|
||||||
}
|
}
|
||||||
public bool NfcEnabled => Utilities.NfcEnabled();
|
public bool NfcEnabled => Utilities.NfcEnabled();
|
||||||
public bool HasCamera => Xamarin.Forms.Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera);
|
public bool HasCamera => Xamarin.Forms.Forms.Context.PackageManager.HasSystemFeature(PackageManager.FeatureCamera);
|
||||||
|
public bool AutofillServiceSupported => AutofillSupported();
|
||||||
|
|
||||||
|
private bool AutofillSupported()
|
||||||
|
{
|
||||||
|
if(Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activity = (MainActivity)Xamarin.Forms.Forms.Context;
|
||||||
|
var afm = (AutofillManager)activity.GetSystemService(Java.Lang.Class.FromType(typeof(AutofillManager)));
|
||||||
|
return afm.IsAutofillSupported;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
{
|
{
|
||||||
string Build { get; }
|
string Build { get; }
|
||||||
string Version { get; }
|
string Version { get; }
|
||||||
|
bool AutofillAccessibilityServiceEnabled { get; }
|
||||||
bool AutofillServiceEnabled { get; }
|
bool AutofillServiceEnabled { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Bit.App.Abstractions
|
||||||
void RateApp();
|
void RateApp();
|
||||||
void DismissKeyboard();
|
void DismissKeyboard();
|
||||||
void OpenAccessibilitySettings();
|
void OpenAccessibilitySettings();
|
||||||
|
void OpenAutofillSettings();
|
||||||
void LaunchApp(string appName);
|
void LaunchApp(string appName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
float Scale { get; }
|
float Scale { get; }
|
||||||
bool NfcEnabled { get; }
|
bool NfcEnabled { get; }
|
||||||
bool HasCamera { get; }
|
bool HasCamera { get; }
|
||||||
|
bool AutofillServiceSupported { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,7 @@
|
||||||
<Compile Include="Pages\Settings\SettingsEditFolderPage.cs" />
|
<Compile Include="Pages\Settings\SettingsEditFolderPage.cs" />
|
||||||
<Compile Include="Pages\Lock\LockFingerprintPage.cs" />
|
<Compile Include="Pages\Lock\LockFingerprintPage.cs" />
|
||||||
<Compile Include="Pages\Settings\SettingsAboutPage.cs" />
|
<Compile Include="Pages\Settings\SettingsAboutPage.cs" />
|
||||||
|
<Compile Include="Pages\Tools\ToolsAutofillServicePage2.cs" />
|
||||||
<Compile Include="Pages\Tools\ToolsAutofillServicePage.cs" />
|
<Compile Include="Pages\Tools\ToolsAutofillServicePage.cs" />
|
||||||
<Compile Include="Pages\Tools\ToolsExtensionPage.cs" />
|
<Compile Include="Pages\Tools\ToolsExtensionPage.cs" />
|
||||||
<Compile Include="Pages\Tools\ToolsPasswordGeneratorSettingsPage.cs" />
|
<Compile Include="Pages\Tools\ToolsPasswordGeneratorSettingsPage.cs" />
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void UpdateEnabled()
|
private void UpdateEnabled()
|
||||||
{
|
{
|
||||||
ScrollView.Content = _appInfoService.AutofillServiceEnabled ? EnabledStackLayout : DisabledStackLayout;
|
ScrollView.Content = _appInfoService.AutofillAccessibilityServiceEnabled ? EnabledStackLayout : DisabledStackLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Label BuildServiceLabel()
|
private Label BuildServiceLabel()
|
||||||
|
|
153
src/App/Pages/Tools/ToolsAutofillServicePage2.cs
Normal file
153
src/App/Pages/Tools/ToolsAutofillServicePage2.cs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
using System;
|
||||||
|
using Bit.App.Controls;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
using XLabs.Ioc;
|
||||||
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Resources;
|
||||||
|
|
||||||
|
namespace Bit.App.Pages
|
||||||
|
{
|
||||||
|
public class ToolsAutofillServicePage2 : ExtendedContentPage
|
||||||
|
{
|
||||||
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
|
private readonly IAppInfoService _appInfoService;
|
||||||
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
|
private bool _pageDisappeared = false;
|
||||||
|
|
||||||
|
public ToolsAutofillServicePage2()
|
||||||
|
{
|
||||||
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||||
|
_appInfoService = Resolver.Resolve<IAppInfoService>();
|
||||||
|
_deviceActionService = Resolver.Resolve<IDeviceActionService>();
|
||||||
|
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StackLayout EnabledStackLayout { get; set; }
|
||||||
|
public StackLayout DisabledStackLayout { get; set; }
|
||||||
|
public ScrollView ScrollView { get; set; }
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
var enabledFs = new FormattedString();
|
||||||
|
var statusSpan = new Span { Text = string.Concat(AppResources.Status, " ") };
|
||||||
|
enabledFs.Spans.Add(statusSpan);
|
||||||
|
enabledFs.Spans.Add(new Span
|
||||||
|
{
|
||||||
|
Text = AppResources.Enabled,
|
||||||
|
ForegroundColor = Color.Green,
|
||||||
|
FontAttributes = FontAttributes.Bold,
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
|
||||||
|
});
|
||||||
|
|
||||||
|
var statusEnabledLabel = new Label
|
||||||
|
{
|
||||||
|
FormattedText = enabledFs,
|
||||||
|
HorizontalTextAlignment = TextAlignment.Center,
|
||||||
|
LineBreakMode = LineBreakMode.WordWrap,
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||||
|
TextColor = Color.Black
|
||||||
|
};
|
||||||
|
|
||||||
|
var disabledFs = new FormattedString();
|
||||||
|
disabledFs.Spans.Add(statusSpan);
|
||||||
|
disabledFs.Spans.Add(new Span
|
||||||
|
{
|
||||||
|
Text = AppResources.Disabled,
|
||||||
|
ForegroundColor = Color.FromHex("c62929"),
|
||||||
|
FontAttributes = FontAttributes.Bold,
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
|
||||||
|
});
|
||||||
|
|
||||||
|
var statusDisabledLabel = new Label
|
||||||
|
{
|
||||||
|
FormattedText = disabledFs,
|
||||||
|
HorizontalTextAlignment = TextAlignment.Center,
|
||||||
|
LineBreakMode = LineBreakMode.WordWrap,
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)),
|
||||||
|
TextColor = Color.Black
|
||||||
|
};
|
||||||
|
|
||||||
|
DisabledStackLayout = new StackLayout
|
||||||
|
{
|
||||||
|
Children = { BuildServiceLabel(), statusDisabledLabel, BuildGoButton() },
|
||||||
|
Orientation = StackOrientation.Vertical,
|
||||||
|
Spacing = 20,
|
||||||
|
Padding = new Thickness(20, 30),
|
||||||
|
VerticalOptions = LayoutOptions.FillAndExpand
|
||||||
|
};
|
||||||
|
|
||||||
|
EnabledStackLayout = new StackLayout
|
||||||
|
{
|
||||||
|
Children = { BuildServiceLabel(), statusEnabledLabel },
|
||||||
|
Orientation = StackOrientation.Vertical,
|
||||||
|
Spacing = 20,
|
||||||
|
Padding = new Thickness(20, 30),
|
||||||
|
VerticalOptions = LayoutOptions.FillAndExpand
|
||||||
|
};
|
||||||
|
|
||||||
|
ScrollView = new ScrollView { Content = DisabledStackLayout };
|
||||||
|
|
||||||
|
UpdateEnabled();
|
||||||
|
Device.StartTimer(new TimeSpan(0, 0, 3), () =>
|
||||||
|
{
|
||||||
|
if(_pageDisappeared)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateEnabled();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
Title = AppResources.AutofillService;
|
||||||
|
Content = ScrollView;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAppearing()
|
||||||
|
{
|
||||||
|
_pageDisappeared = false;
|
||||||
|
base.OnAppearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDisappearing()
|
||||||
|
{
|
||||||
|
_pageDisappeared = true;
|
||||||
|
base.OnDisappearing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateEnabled()
|
||||||
|
{
|
||||||
|
ScrollView.Content = _appInfoService.AutofillServiceEnabled ? EnabledStackLayout : DisabledStackLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label BuildServiceLabel()
|
||||||
|
{
|
||||||
|
return new Label
|
||||||
|
{
|
||||||
|
Text = AppResources.AutofillDescription,
|
||||||
|
VerticalOptions = LayoutOptions.Start,
|
||||||
|
HorizontalTextAlignment = TextAlignment.Center,
|
||||||
|
LineBreakMode = LineBreakMode.WordWrap,
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Small, typeof(Label))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExtendedButton BuildGoButton()
|
||||||
|
{
|
||||||
|
return new ExtendedButton
|
||||||
|
{
|
||||||
|
Text = AppResources.BitwardenAutofillServiceOpenSettings,
|
||||||
|
Command = new Command(() =>
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackAppEvent("OpenAutofillSettings");
|
||||||
|
_deviceActionService.OpenAutofillSettings();
|
||||||
|
}),
|
||||||
|
VerticalOptions = LayoutOptions.End,
|
||||||
|
HorizontalOptions = LayoutOptions.Fill,
|
||||||
|
Style = (Style)Application.Current.Resources["btn-primary"],
|
||||||
|
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Button))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,11 +15,13 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
private readonly IUserDialogs _userDialogs;
|
private readonly IUserDialogs _userDialogs;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
|
private readonly IDeviceInfoService _deviceInfoService;
|
||||||
|
|
||||||
public ToolsPage()
|
public ToolsPage()
|
||||||
{
|
{
|
||||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||||
|
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -116,7 +118,14 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void AutofillCell_Tapped(object sender, EventArgs e)
|
private void AutofillCell_Tapped(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Navigation.PushModalAsync(new ExtendedNavigationPage(new ToolsAutofillServicePage()));
|
if(_deviceInfoService.AutofillServiceSupported)
|
||||||
|
{
|
||||||
|
Navigation.PushModalAsync(new ExtendedNavigationPage(new ToolsAutofillServicePage2()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Navigation.PushModalAsync(new ExtendedNavigationPage(new ToolsAutofillServicePage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExtensionCell_Tapped(object sender, EventArgs e)
|
private void ExtensionCell_Tapped(object sender, EventArgs e)
|
||||||
|
|
|
@ -242,7 +242,7 @@ namespace Bit.App.Pages
|
||||||
DisplayAlert(AppResources.BitwardenAppExtension, AppResources.BitwardenAppExtensionAlert,
|
DisplayAlert(AppResources.BitwardenAppExtension, AppResources.BitwardenAppExtensionAlert,
|
||||||
AppResources.Ok);
|
AppResources.Ok);
|
||||||
}
|
}
|
||||||
else if(Device.RuntimePlatform == Device.Android && !_appInfoService.AutofillServiceEnabled)
|
else if(Device.RuntimePlatform == Device.Android && !_appInfoService.AutofillAccessibilityServiceEnabled)
|
||||||
{
|
{
|
||||||
DisplayAlert(AppResources.BitwardenAutofillService, AppResources.BitwardenAutofillServiceAlert,
|
DisplayAlert(AppResources.BitwardenAutofillService, AppResources.BitwardenAutofillServiceAlert,
|
||||||
AppResources.Ok);
|
AppResources.Ok);
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Bit.UWP.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AutofillAccessibilityServiceEnabled => false;
|
||||||
public bool AutofillServiceEnabled => false;
|
public bool AutofillServiceEnabled => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,11 @@ namespace Bit.UWP.Services
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenAutofillSettings()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public Task SelectFileAsync()
|
public Task SelectFileAsync()
|
||||||
{
|
{
|
||||||
var picker = new Windows.Storage.Pickers.FileOpenPicker
|
var picker = new Windows.Storage.Pickers.FileOpenPicker
|
||||||
|
|
|
@ -39,5 +39,7 @@ namespace Bit.UWP.Services
|
||||||
return cameraList?.Any() ?? false;
|
return cameraList?.Any() ?? false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool AutofillServiceSupported => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,6 @@ namespace Bit.iOS.Core.Services
|
||||||
public float Scale => (float)UIScreen.MainScreen.Scale;
|
public float Scale => (float)UIScreen.MainScreen.Scale;
|
||||||
public bool NfcEnabled => false;
|
public bool NfcEnabled => false;
|
||||||
public bool HasCamera => true;
|
public bool HasCamera => true;
|
||||||
|
public bool AutofillServiceSupported => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Bit.iOS.Services
|
||||||
{
|
{
|
||||||
public string Build => NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString();
|
public string Build => NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString();
|
||||||
public string Version => NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"].ToString();
|
public string Version => NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"].ToString();
|
||||||
|
public bool AutofillAccessibilityServiceEnabled => false;
|
||||||
public bool AutofillServiceEnabled => false;
|
public bool AutofillServiceEnabled => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,5 +250,10 @@ namespace Bit.iOS.Services
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenAutofillSettings()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue