From 52a866147ee8ef2d1874addc4932a4489e8aa62b Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Sun, 5 Feb 2017 23:55:46 -0500 Subject: [PATCH] Optimized startup tasks to only happen when necessary. Added some GA telemetry to autofill. --- src/Android/MainActivity.cs | 3 +- src/App/App.cs | 30 +++++++++----- .../Pages/Tools/ToolsPasswordGeneratorPage.cs | 41 ++++++++++++++++--- src/App/Pages/Vault/VaultAddLoginPage.cs | 15 +++++-- .../Vault/VaultAutofillListLoginsPage.cs | 20 +++++---- src/iOS/AppDelegate.cs | 3 +- 6 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/Android/MainActivity.cs b/src/Android/MainActivity.cs index 6db3f07db..902116edf 100644 --- a/src/Android/MainActivity.cs +++ b/src/Android/MainActivity.cs @@ -77,7 +77,8 @@ namespace Bit.Android Resolver.Resolve(), Resolver.Resolve(), Resolver.Resolve(), - Resolver.Resolve())); + Resolver.Resolve(), + Resolver.Resolve())); MessagingCenter.Subscribe(Xamarin.Forms.Application.Current, "RateApp", (sender) => { diff --git a/src/App/App.cs b/src/App/App.cs index e152c972c..a9fd2e00d 100644 --- a/src/App/App.cs +++ b/src/App/App.cs @@ -20,6 +20,8 @@ namespace Bit.App { public class App : Application { + private const string LastBuildKey = "LastBuild"; + private string _uri; private readonly IDatabaseService _databaseService; private readonly IConnectivity _connectivity; @@ -31,6 +33,7 @@ namespace Bit.App private readonly ILockService _lockService; private readonly IGoogleAnalyticsService _googleAnalyticsService; private readonly ILocalizeService _localizeService; + private readonly IAppInfoService _appInfoService; private CancellationTokenSource _setMainPageCancellationTokenSource = null; public static bool FromAutofillService { get; set; } = false; @@ -46,7 +49,8 @@ namespace Bit.App ISettings settings, ILockService lockService, IGoogleAnalyticsService googleAnalyticsService, - ILocalizeService localizeService) + ILocalizeService localizeService, + IAppInfoService appInfoService) { _uri = uri; _databaseService = databaseService; @@ -59,6 +63,7 @@ namespace Bit.App _lockService = lockService; _googleAnalyticsService = googleAnalyticsService; _localizeService = localizeService; + _appInfoService = appInfoService; SetCulture(); SetStyles(); @@ -93,14 +98,9 @@ namespace Bit.App Device.BeginInvokeOnMainThread(() => Logout(args)); }); - MessagingCenter.Subscribe(Current, "SetMainPage", (sender) => + MessagingCenter.Subscribe(Current, "SetMainPage", (sender, ms) => { - _setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, 500); - }); - - MessagingCenter.Subscribe(Current, "SetMainPageNow", (sender) => - { - _setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, 0); + _setMainPageCancellationTokenSource = SetMainPageFromAutofill(_setMainPageCancellationTokenSource, ms); }); } @@ -108,8 +108,18 @@ namespace Bit.App { // Handle when your app starts await CheckLockAsync(false); - _databaseService.CreateTables(); - await Task.Run(() => FullSyncAsync()).ConfigureAwait(false); + + if(!FromAutofillService) + { + var lastBuild = _settings.GetValueOrDefault(LastBuildKey); + if(lastBuild == null || lastBuild != _appInfoService.Build) + { + _settings.AddOrUpdateValue(LastBuildKey, _appInfoService.Build); + _databaseService.CreateTables(); + } + + await Task.Run(() => FullSyncAsync()).ConfigureAwait(false); + } Debug.WriteLine("OnStart"); } diff --git a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs index 9ada40a8a..43346110c 100644 --- a/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs +++ b/src/App/Pages/Tools/ToolsPasswordGeneratorPage.cs @@ -18,8 +18,9 @@ namespace Bit.App.Pages private readonly IClipboardService _clipboardService; private readonly IGoogleAnalyticsService _googleAnalyticsService; private readonly Action _passwordValueAction; + private readonly bool _fromAutofill; - public ToolsPasswordGeneratorPage(Action passwordValueAction = null) + public ToolsPasswordGeneratorPage(Action passwordValueAction = null, bool fromAutofill = false) { _userDialogs = Resolver.Resolve(); _passwordGenerationService = Resolver.Resolve(); @@ -27,6 +28,7 @@ namespace Bit.App.Pages _clipboardService = Resolver.Resolve(); _googleAnalyticsService = Resolver.Resolve(); _passwordValueAction = passwordValueAction; + _fromAutofill = fromAutofill; Init(); } @@ -111,7 +113,15 @@ namespace Bit.App.Pages { var selectToolBarItem = new ToolbarItem(AppResources.Select, null, async () => { - _googleAnalyticsService.TrackAppEvent("SelectedGeneratedPassword"); + if(_fromAutofill) + { + _googleAnalyticsService.TrackExtensionEvent("SelectedGeneratedPassword"); + } + else + { + _googleAnalyticsService.TrackAppEvent("SelectedGeneratedPassword"); + } + _passwordValueAction(Password.Text); await Navigation.PopForDeviceAsync(); }, ToolbarItemOrder.Default, 0); @@ -132,7 +142,14 @@ namespace Bit.App.Pages protected override void OnAppearing() { base.OnAppearing(); - _googleAnalyticsService.TrackAppEvent("GeneratedPassword"); + if(_fromAutofill) + { + _googleAnalyticsService.TrackExtensionEvent("GeneratedPassword"); + } + else + { + _googleAnalyticsService.TrackAppEvent("GeneratedPassword"); + } Model.Password = _passwordGenerationService.GeneratePassword(); Model.Length = _settings.GetValueOrDefault(Constants.PasswordGeneratorLength, 10).ToString(); } @@ -140,7 +157,14 @@ namespace Bit.App.Pages private void RegenerateCell_Tapped(object sender, EventArgs e) { Model.Password = _passwordGenerationService.GeneratePassword(); - _googleAnalyticsService.TrackAppEvent("RegeneratedPassword"); + if(_fromAutofill) + { + _googleAnalyticsService.TrackExtensionEvent("RegeneratedPassword"); + } + else + { + _googleAnalyticsService.TrackAppEvent("RegeneratedPassword"); + } } private void CopyCell_Tapped(object sender, EventArgs e) @@ -155,7 +179,14 @@ namespace Bit.App.Pages private void CopyPassword() { - _googleAnalyticsService.TrackAppEvent("CopiedGeneratedPassword"); + if(_fromAutofill) + { + _googleAnalyticsService.TrackExtensionEvent("CopiedGeneratedPassword"); + } + else + { + _googleAnalyticsService.TrackAppEvent("CopiedGeneratedPassword"); + } _clipboardService.CopyToClipboard(Password.Text); _userDialogs.Toast(string.Format(AppResources.ValueHasBeenCopied, AppResources.Password)); } diff --git a/src/App/Pages/Vault/VaultAddLoginPage.cs b/src/App/Pages/Vault/VaultAddLoginPage.cs index 879c6540e..2651a16c3 100644 --- a/src/App/Pages/Vault/VaultAddLoginPage.cs +++ b/src/App/Pages/Vault/VaultAddLoginPage.cs @@ -25,11 +25,13 @@ namespace Bit.App.Pages private readonly ISettings _settings; private readonly string _defaultUri; 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; _defaultName = defaultName; + _fromAutofill = fromAutofill; _loginService = Resolver.Resolve(); _folderService = Resolver.Resolve(); @@ -163,7 +165,14 @@ namespace Bit.App.Pages { await Navigation.PopForDeviceAsync(); _userDialogs.Toast(AppResources.NewLoginCreated); - _googleAnalyticsService.TrackAppEvent("CreatedLogin"); + if(_fromAutofill) + { + _googleAnalyticsService.TrackExtensionEvent("CreatedLogin"); + } + else + { + _googleAnalyticsService.TrackAppEvent("CreatedLogin"); + } } else if(saveTask.Errors.Count() > 0) { @@ -211,7 +220,7 @@ namespace Bit.App.Pages { PasswordCell.Entry.Text = password; _userDialogs.Toast(AppResources.PasswordGenerated); - }); + }, _fromAutofill); await Navigation.PushForDeviceAsync(page); } diff --git a/src/App/Pages/Vault/VaultAutofillListLoginsPage.cs b/src/App/Pages/Vault/VaultAutofillListLoginsPage.cs index 59ba9060b..4d1e401aa 100644 --- a/src/App/Pages/Vault/VaultAutofillListLoginsPage.cs +++ b/src/App/Pages/Vault/VaultAutofillListLoginsPage.cs @@ -23,16 +23,15 @@ namespace Bit.App.Pages private readonly IClipboardService _clipboardService; private CancellationTokenSource _filterResultsCancellationTokenSource; private readonly DomainName _domainName; - private readonly string _uri; private readonly string _name; private readonly bool _androidApp = false; public VaultAutofillListLoginsPage(string uriString) : base(true) { - _uri = uriString; + Uri = uriString; 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)) { if(uriString != null && uriString.StartsWith(Constants.AndroidAppProtocol)) @@ -50,14 +49,18 @@ namespace Bit.App.Pages _deviceInfoService = Resolver.Resolve(); _userDialogs = Resolver.Resolve(); _clipboardService = Resolver.Resolve(); + GoogleAnalyticsService = Resolver.Resolve(); Init(); } + public ExtendedObservableCollection PresentationLogins { get; private set; } = new ExtendedObservableCollection(); public StackLayout NoDataStackLayout { get; set; } public ListView ListView { get; set; } public ActivityIndicator LoadingIndicator { get; set; } + private IGoogleAnalyticsService GoogleAnalyticsService { get; set; } + private string Uri { get; set; } private void Init() { @@ -122,6 +125,7 @@ namespace Bit.App.Pages protected override bool OnBackButtonPressed() { + GoogleAnalyticsService.TrackExtensionEvent("BackClosed", Uri.StartsWith("http") ? "Website" : "App"); MessagingCenter.Send(Application.Current, "Autofill", (VaultListPageModel.Login)null); return true; } @@ -148,7 +152,7 @@ namespace Bit.App.Pages var logins = await _loginService.GetAllAsync(); var filteredLogins = logins .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)) .OrderBy(s => s.Name) .ThenBy(s => s.Username); @@ -167,18 +171,19 @@ namespace Bit.App.Pages { var login = e.SelectedItem as VaultListPageModel.Login; - if(_uri.StartsWith("http") && _deviceInfoService.Version < 21) + if(Uri.StartsWith("http") && _deviceInfoService.Version < 21) { MoreClickedAsync(login); return; } + GoogleAnalyticsService.TrackExtensionEvent("AutoFilled", Uri.StartsWith("http") ? "Website" : "App"); MessagingCenter.Send(Application.Current, "Autofill", login); } private async void AddLoginAsync() { - var page = new VaultAddLoginPage(_uri, _name); + var page = new VaultAddLoginPage(Uri, _name, true); await Navigation.PushForDeviceAsync(page); } @@ -256,7 +261,8 @@ namespace Bit.App.Pages 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); } } } diff --git a/src/iOS/AppDelegate.cs b/src/iOS/AppDelegate.cs index c67705add..d30038ced 100644 --- a/src/iOS/AppDelegate.cs +++ b/src/iOS/AppDelegate.cs @@ -66,7 +66,8 @@ namespace Bit.iOS Resolver.Resolve(), Resolver.Resolve(), Resolver.Resolve(), - Resolver.Resolve())); + Resolver.Resolve(), + Resolver.Resolve())); // Appearance stuff