mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 23:25:45 +03:00
Optimized startup tasks to only happen when necessary. Added some GA telemetry to autofill.
This commit is contained in:
parent
6629eaf485
commit
52a866147e
6 changed files with 85 additions and 27 deletions
|
@ -77,7 +77,8 @@ namespace Bit.Android
|
||||||
Resolver.Resolve<ISettings>(),
|
Resolver.Resolve<ISettings>(),
|
||||||
Resolver.Resolve<ILockService>(),
|
Resolver.Resolve<ILockService>(),
|
||||||
Resolver.Resolve<IGoogleAnalyticsService>(),
|
Resolver.Resolve<IGoogleAnalyticsService>(),
|
||||||
Resolver.Resolve<ILocalizeService>()));
|
Resolver.Resolve<ILocalizeService>(),
|
||||||
|
Resolver.Resolve<IAppInfoService>()));
|
||||||
|
|
||||||
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, "RateApp", (sender) =>
|
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, "RateApp", (sender) =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,8 @@ namespace Bit.App
|
||||||
{
|
{
|
||||||
public class App : Application
|
public class App : Application
|
||||||
{
|
{
|
||||||
|
private const string LastBuildKey = "LastBuild";
|
||||||
|
|
||||||
private string _uri;
|
private string _uri;
|
||||||
private readonly IDatabaseService _databaseService;
|
private readonly IDatabaseService _databaseService;
|
||||||
private readonly IConnectivity _connectivity;
|
private readonly IConnectivity _connectivity;
|
||||||
|
@ -31,6 +33,7 @@ namespace Bit.App
|
||||||
private readonly ILockService _lockService;
|
private readonly ILockService _lockService;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
private readonly ILocalizeService _localizeService;
|
private readonly ILocalizeService _localizeService;
|
||||||
|
private readonly IAppInfoService _appInfoService;
|
||||||
private CancellationTokenSource _setMainPageCancellationTokenSource = null;
|
private CancellationTokenSource _setMainPageCancellationTokenSource = null;
|
||||||
|
|
||||||
public static bool FromAutofillService { get; set; } = false;
|
public static bool FromAutofillService { get; set; } = false;
|
||||||
|
@ -46,7 +49,8 @@ namespace Bit.App
|
||||||
ISettings settings,
|
ISettings settings,
|
||||||
ILockService lockService,
|
ILockService lockService,
|
||||||
IGoogleAnalyticsService googleAnalyticsService,
|
IGoogleAnalyticsService googleAnalyticsService,
|
||||||
ILocalizeService localizeService)
|
ILocalizeService localizeService,
|
||||||
|
IAppInfoService appInfoService)
|
||||||
{
|
{
|
||||||
_uri = uri;
|
_uri = uri;
|
||||||
_databaseService = databaseService;
|
_databaseService = databaseService;
|
||||||
|
@ -59,6 +63,7 @@ namespace Bit.App
|
||||||
_lockService = lockService;
|
_lockService = lockService;
|
||||||
_googleAnalyticsService = googleAnalyticsService;
|
_googleAnalyticsService = googleAnalyticsService;
|
||||||
_localizeService = localizeService;
|
_localizeService = localizeService;
|
||||||
|
_appInfoService = appInfoService;
|
||||||
|
|
||||||
SetCulture();
|
SetCulture();
|
||||||
SetStyles();
|
SetStyles();
|
||||||
|
@ -93,14 +98,9 @@ namespace Bit.App
|
||||||
Device.BeginInvokeOnMainThread(() => Logout(args));
|
Device.BeginInvokeOnMainThread(() => Logout(args));
|
||||||
});
|
});
|
||||||
|
|
||||||
MessagingCenter.Subscribe<Application>(Current, "SetMainPage", (sender) =>
|
MessagingCenter.Subscribe<Application, int>(Current, "SetMainPage", (sender, ms) =>
|
||||||
{
|
{
|
||||||
_setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, 500);
|
_setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, ms);
|
||||||
});
|
|
||||||
|
|
||||||
MessagingCenter.Subscribe<Application>(Current, "SetMainPageNow", (sender) =>
|
|
||||||
{
|
|
||||||
_setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, 0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +108,18 @@ namespace Bit.App
|
||||||
{
|
{
|
||||||
// Handle when your app starts
|
// Handle when your app starts
|
||||||
await CheckLockAsync(false);
|
await CheckLockAsync(false);
|
||||||
|
|
||||||
|
if(!FromAutofillService)
|
||||||
|
{
|
||||||
|
var lastBuild = _settings.GetValueOrDefault<string>(LastBuildKey);
|
||||||
|
if(lastBuild == null || lastBuild != _appInfoService.Build)
|
||||||
|
{
|
||||||
|
_settings.AddOrUpdateValue(LastBuildKey, _appInfoService.Build);
|
||||||
_databaseService.CreateTables();
|
_databaseService.CreateTables();
|
||||||
|
}
|
||||||
|
|
||||||
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
|
await Task.Run(() => FullSyncAsync()).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
Debug.WriteLine("OnStart");
|
Debug.WriteLine("OnStart");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,9 @@ namespace Bit.App.Pages
|
||||||
private readonly IClipboardService _clipboardService;
|
private readonly IClipboardService _clipboardService;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
private readonly Action<string> _passwordValueAction;
|
private readonly Action<string> _passwordValueAction;
|
||||||
|
private readonly bool _fromAutofill;
|
||||||
|
|
||||||
public ToolsPasswordGeneratorPage(Action<string> passwordValueAction = null)
|
public ToolsPasswordGeneratorPage(Action<string> passwordValueAction = null, bool fromAutofill = false)
|
||||||
{
|
{
|
||||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||||
_passwordGenerationService = Resolver.Resolve<IPasswordGenerationService>();
|
_passwordGenerationService = Resolver.Resolve<IPasswordGenerationService>();
|
||||||
|
@ -27,6 +28,7 @@ namespace Bit.App.Pages
|
||||||
_clipboardService = Resolver.Resolve<IClipboardService>();
|
_clipboardService = Resolver.Resolve<IClipboardService>();
|
||||||
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
_googleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||||
_passwordValueAction = passwordValueAction;
|
_passwordValueAction = passwordValueAction;
|
||||||
|
_fromAutofill = fromAutofill;
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
@ -110,8 +112,16 @@ namespace Bit.App.Pages
|
||||||
if(_passwordValueAction != null)
|
if(_passwordValueAction != null)
|
||||||
{
|
{
|
||||||
var selectToolBarItem = new ToolbarItem(AppResources.Select, null, async () =>
|
var selectToolBarItem = new ToolbarItem(AppResources.Select, null, async () =>
|
||||||
|
{
|
||||||
|
if(_fromAutofill)
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("SelectedGeneratedPassword");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_googleAnalyticsService.TrackAppEvent("SelectedGeneratedPassword");
|
_googleAnalyticsService.TrackAppEvent("SelectedGeneratedPassword");
|
||||||
|
}
|
||||||
|
|
||||||
_passwordValueAction(Password.Text);
|
_passwordValueAction(Password.Text);
|
||||||
await Navigation.PopForDeviceAsync();
|
await Navigation.PopForDeviceAsync();
|
||||||
}, ToolbarItemOrder.Default, 0);
|
}, ToolbarItemOrder.Default, 0);
|
||||||
|
@ -132,7 +142,14 @@ namespace Bit.App.Pages
|
||||||
protected override void OnAppearing()
|
protected override void OnAppearing()
|
||||||
{
|
{
|
||||||
base.OnAppearing();
|
base.OnAppearing();
|
||||||
|
if(_fromAutofill)
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("GeneratedPassword");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_googleAnalyticsService.TrackAppEvent("GeneratedPassword");
|
_googleAnalyticsService.TrackAppEvent("GeneratedPassword");
|
||||||
|
}
|
||||||
Model.Password = _passwordGenerationService.GeneratePassword();
|
Model.Password = _passwordGenerationService.GeneratePassword();
|
||||||
Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString();
|
Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString();
|
||||||
}
|
}
|
||||||
|
@ -140,8 +157,15 @@ namespace Bit.App.Pages
|
||||||
private void RegenerateCell_Tapped(object sender, EventArgs e)
|
private void RegenerateCell_Tapped(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Model.Password = _passwordGenerationService.GeneratePassword();
|
Model.Password = _passwordGenerationService.GeneratePassword();
|
||||||
|
if(_fromAutofill)
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("RegeneratedPassword");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_googleAnalyticsService.TrackAppEvent("RegeneratedPassword");
|
_googleAnalyticsService.TrackAppEvent("RegeneratedPassword");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CopyCell_Tapped(object sender, EventArgs e)
|
private void CopyCell_Tapped(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
@ -154,8 +178,15 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CopyPassword()
|
private void CopyPassword()
|
||||||
|
{
|
||||||
|
if(_fromAutofill)
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("CopiedGeneratedPassword");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
_googleAnalyticsService.TrackAppEvent("CopiedGeneratedPassword");
|
_googleAnalyticsService.TrackAppEvent("CopiedGeneratedPassword");
|
||||||
|
}
|
||||||
_clipboardService.CopyToClipboard(Password.Text);
|
_clipboardService.CopyToClipboard(Password.Text);
|
||||||
_userDialogs.Toast(string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
_userDialogs.Toast(string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@ namespace Bit.App.Pages
|
||||||
private readonly ISettings _settings;
|
private readonly ISettings _settings;
|
||||||
private readonly string _defaultUri;
|
private readonly string _defaultUri;
|
||||||
private readonly string _defaultName;
|
private readonly string _defaultName;
|
||||||
|
private readonly bool _fromAutofill;
|
||||||
|
|
||||||
public VaultAddLoginPage(string defaultUri = null, string defaultName = null)
|
public VaultAddLoginPage(string defaultUri = null, string defaultName = null, bool fromAutofill = false)
|
||||||
{
|
{
|
||||||
_defaultUri = defaultUri;
|
_defaultUri = defaultUri;
|
||||||
_defaultName = defaultName;
|
_defaultName = defaultName;
|
||||||
|
_fromAutofill = fromAutofill;
|
||||||
|
|
||||||
_loginService = Resolver.Resolve<ILoginService>();
|
_loginService = Resolver.Resolve<ILoginService>();
|
||||||
_folderService = Resolver.Resolve<IFolderService>();
|
_folderService = Resolver.Resolve<IFolderService>();
|
||||||
|
@ -163,8 +165,15 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
await Navigation.PopForDeviceAsync();
|
await Navigation.PopForDeviceAsync();
|
||||||
_userDialogs.Toast(AppResources.NewLoginCreated);
|
_userDialogs.Toast(AppResources.NewLoginCreated);
|
||||||
|
if(_fromAutofill)
|
||||||
|
{
|
||||||
|
_googleAnalyticsService.TrackExtensionEvent("CreatedLogin");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_googleAnalyticsService.TrackAppEvent("CreatedLogin");
|
_googleAnalyticsService.TrackAppEvent("CreatedLogin");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(saveTask.Errors.Count() > 0)
|
else if(saveTask.Errors.Count() > 0)
|
||||||
{
|
{
|
||||||
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred);
|
await _userDialogs.AlertAsync(saveTask.Errors.First().Message, AppResources.AnErrorHasOccurred);
|
||||||
|
@ -211,7 +220,7 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
PasswordCell.Entry.Text = password;
|
PasswordCell.Entry.Text = password;
|
||||||
_userDialogs.Toast(AppResources.PasswordGenerated);
|
_userDialogs.Toast(AppResources.PasswordGenerated);
|
||||||
});
|
}, _fromAutofill);
|
||||||
await Navigation.PushForDeviceAsync(page);
|
await Navigation.PushForDeviceAsync(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,15 @@ namespace Bit.App.Pages
|
||||||
private readonly IClipboardService _clipboardService;
|
private readonly IClipboardService _clipboardService;
|
||||||
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
private CancellationTokenSource _filterResultsCancellationTokenSource;
|
||||||
private readonly DomainName _domainName;
|
private readonly DomainName _domainName;
|
||||||
private readonly string _uri;
|
|
||||||
private readonly string _name;
|
private readonly string _name;
|
||||||
private readonly bool _androidApp = false;
|
private readonly bool _androidApp = false;
|
||||||
|
|
||||||
public VaultAutofillListLoginsPage(string uriString)
|
public VaultAutofillListLoginsPage(string uriString)
|
||||||
: base(true)
|
: base(true)
|
||||||
{
|
{
|
||||||
_uri = uriString;
|
Uri = uriString;
|
||||||
Uri uri;
|
Uri uri;
|
||||||
if(!Uri.TryCreate(uriString, UriKind.Absolute, out uri) ||
|
if(!System.Uri.TryCreate(uriString, UriKind.Absolute, out uri) ||
|
||||||
!DomainName.TryParse(uri.Host, out _domainName))
|
!DomainName.TryParse(uri.Host, out _domainName))
|
||||||
{
|
{
|
||||||
if(uriString != null && uriString.StartsWith(Constants.AndroidAppProtocol))
|
if(uriString != null && uriString.StartsWith(Constants.AndroidAppProtocol))
|
||||||
|
@ -50,14 +49,18 @@ namespace Bit.App.Pages
|
||||||
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
_deviceInfoService = Resolver.Resolve<IDeviceInfoService>();
|
||||||
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
_userDialogs = Resolver.Resolve<IUserDialogs>();
|
||||||
_clipboardService = Resolver.Resolve<IClipboardService>();
|
_clipboardService = Resolver.Resolve<IClipboardService>();
|
||||||
|
GoogleAnalyticsService = Resolver.Resolve<IGoogleAnalyticsService>();
|
||||||
|
|
||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExtendedObservableCollection<VaultListPageModel.Login> PresentationLogins { get; private set; }
|
public ExtendedObservableCollection<VaultListPageModel.Login> PresentationLogins { get; private set; }
|
||||||
= new ExtendedObservableCollection<VaultListPageModel.Login>();
|
= new ExtendedObservableCollection<VaultListPageModel.Login>();
|
||||||
public StackLayout NoDataStackLayout { get; set; }
|
public StackLayout NoDataStackLayout { get; set; }
|
||||||
public ListView ListView { get; set; }
|
public ListView ListView { get; set; }
|
||||||
public ActivityIndicator LoadingIndicator { get; set; }
|
public ActivityIndicator LoadingIndicator { get; set; }
|
||||||
|
private IGoogleAnalyticsService GoogleAnalyticsService { get; set; }
|
||||||
|
private string Uri { get; set; }
|
||||||
|
|
||||||
private void Init()
|
private void Init()
|
||||||
{
|
{
|
||||||
|
@ -122,6 +125,7 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
protected override bool OnBackButtonPressed()
|
protected override bool OnBackButtonPressed()
|
||||||
{
|
{
|
||||||
|
GoogleAnalyticsService.TrackExtensionEvent("BackClosed", Uri.StartsWith("http") ? "Website" : "App");
|
||||||
MessagingCenter.Send(Application.Current, "Autofill", (VaultListPageModel.Login)null);
|
MessagingCenter.Send(Application.Current, "Autofill", (VaultListPageModel.Login)null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -148,7 +152,7 @@ namespace Bit.App.Pages
|
||||||
var logins = await _loginService.GetAllAsync();
|
var logins = await _loginService.GetAllAsync();
|
||||||
var filteredLogins = logins
|
var filteredLogins = logins
|
||||||
.Select(s => new VaultListPageModel.Login(s))
|
.Select(s => new VaultListPageModel.Login(s))
|
||||||
.Where(s => (_androidApp && _domainName == null && s.Uri.Value == _uri) ||
|
.Where(s => (_androidApp && _domainName == null && s.Uri.Value == Uri) ||
|
||||||
(_domainName != null && s.BaseDomain != null && s.BaseDomain == _domainName.BaseDomain))
|
(_domainName != null && s.BaseDomain != null && s.BaseDomain == _domainName.BaseDomain))
|
||||||
.OrderBy(s => s.Name)
|
.OrderBy(s => s.Name)
|
||||||
.ThenBy(s => s.Username);
|
.ThenBy(s => s.Username);
|
||||||
|
@ -167,18 +171,19 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
var login = e.SelectedItem as VaultListPageModel.Login;
|
var login = e.SelectedItem as VaultListPageModel.Login;
|
||||||
|
|
||||||
if(_uri.StartsWith("http") && _deviceInfoService.Version < 21)
|
if(Uri.StartsWith("http") && _deviceInfoService.Version < 21)
|
||||||
{
|
{
|
||||||
MoreClickedAsync(login);
|
MoreClickedAsync(login);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GoogleAnalyticsService.TrackExtensionEvent("AutoFilled", Uri.StartsWith("http") ? "Website" : "App");
|
||||||
MessagingCenter.Send(Application.Current, "Autofill", login);
|
MessagingCenter.Send(Application.Current, "Autofill", login);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void AddLoginAsync()
|
private async void AddLoginAsync()
|
||||||
{
|
{
|
||||||
var page = new VaultAddLoginPage(_uri, _name);
|
var page = new VaultAddLoginPage(Uri, _name, true);
|
||||||
await Navigation.PushForDeviceAsync(page);
|
await Navigation.PushForDeviceAsync(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +261,8 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void ClickedItem(object sender, EventArgs e)
|
private void ClickedItem(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
MessagingCenter.Send(Application.Current, "SetMainPageNow");
|
_page.GoogleAnalyticsService.TrackExtensionEvent("Closed", _page.Uri.StartsWith("http") ? "Website" : "App");
|
||||||
|
MessagingCenter.Send(Application.Current, "SetMainPage", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,8 @@ namespace Bit.iOS
|
||||||
Resolver.Resolve<ISettings>(),
|
Resolver.Resolve<ISettings>(),
|
||||||
Resolver.Resolve<ILockService>(),
|
Resolver.Resolve<ILockService>(),
|
||||||
Resolver.Resolve<IGoogleAnalyticsService>(),
|
Resolver.Resolve<IGoogleAnalyticsService>(),
|
||||||
Resolver.Resolve<ILocalizeService>()));
|
Resolver.Resolve<ILocalizeService>(),
|
||||||
|
Resolver.Resolve<IAppInfoService>()));
|
||||||
|
|
||||||
// Appearance stuff
|
// Appearance stuff
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue