PM-3349 Fix navigation when coming from autofill with Accessibility Services enabled. The user was getting into Home page instead of where they were, with this workaround the app navigates as if the account has been switched, leaving the user as closely as possible to where they were, basically on the first screen for the current state of the user.

This commit is contained in:
Federico Maccaroni 2024-01-17 09:34:31 -03:00
parent 0a5d772886
commit 0a1fbfafb5
No known key found for this signature in database
GPG key ID: 5D233F8F2B034536
3 changed files with 41 additions and 5 deletions

View file

@ -46,6 +46,7 @@ namespace Bit.App
// This queue keeps those actions so that when the app has resumed they can still be executed.
// Links: https://github.com/dotnet/maui/issues/11501 and https://bitwarden.atlassian.net/wiki/spaces/NMME/pages/664862722/MainPage+Assignments+not+working+on+Android+on+Background+or+App+resume
private readonly Queue<Action> _onResumeActions = new Queue<Action>();
private bool _hasNavigatedToAutofillWindow;
#if ANDROID
@ -106,18 +107,37 @@ namespace Bit.App
if (Options != null && (Options.FromAutofillFramework || Options.Uri != null || Options.OtpData != null || Options.CreateSend != null))
{
_isResumed = true; //Specifically for the Autofill scenario we need to manually set the _isResumed here
_hasNavigatedToAutofillWindow = true;
return new AutoFillWindow(new NavigationPage(new AndroidNavigationRedirectPage()));
}
var homePage = new HomePage(Options);
// WORKAROUND: If the user autofills with Accessibility Services enabled and goes back to the application then there is currently an issue
// where this method is called again
// thus it goes through here and the user goes to HomePage as we see here.
// So to solve this, the next flag check has been added which then turns on a flag on the home page
// that will trigger a navigation on the accounts manager when it loads; workarounding this behavior and navigating the user
// to the proper page depending on its state.
// WARNING: this doens't navigate the user to where they were but it acts as if the user had changed their account.
if(_hasNavigatedToAutofillWindow)
{
homePage.PerformNavigationOnAccountChangedOnLoad = true;
// this is needed because when coming back from AutofillWindow OnResume won't be called and we need this flag
// so that void Navigate(NavigationTarget navTarget, INavigationParams navParams) doesn't enqueue the navigation
// and it performs it directly.
_isResumed = true;
_hasNavigatedToAutofillWindow = false;
}
//If we have an existing MainAppWindow we can use that one
var mainAppWindow = Windows.OfType<MainAppWindow>().FirstOrDefault();
if (mainAppWindow != null)
{
mainAppWindow.PendingPage = new NavigationPage(new HomePage(Options));
mainAppWindow.PendingPage = new NavigationPage(homePage);
}
//Create new main window
return new MainAppWindow(new NavigationPage(new HomePage(Options)));
return new MainAppWindow(new NavigationPage(homePage));
}
#else
//iOS doesn't use the CreateWindow override used in Android so we just set the Application.Current.MainPage directly

View file

@ -9,6 +9,7 @@
x:DataType="pages:HomeViewModel"
HideSoftInputOnTapped="True"
x:Name="_page"
Loaded="HomePage_Loaded"
Title="{Binding PageTitle}">
<ContentPage.BindingContext>
<pages:HomeViewModel />

View file

@ -1,8 +1,8 @@
using Bit.App.Models;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Microsoft.Maui.Platform;
namespace Bit.App.Pages
{
@ -44,6 +44,21 @@ namespace Bit.App.Pages
}
}
public bool PerformNavigationOnAccountChangedOnLoad { get; internal set; }
void HomePage_Loaded(System.Object sender, System.EventArgs e)
{
#if ANDROID
// WORKAROUND: This is needed to fix the navigation when coming back from autofill when Accessibility Services is enabled
// See App.xaml.cs -> CreateWindow(...) for more info.
if (PerformNavigationOnAccountChangedOnLoad && ServiceContainer.TryResolve<IAccountsManager>(out var accountsManager))
{
PerformNavigationOnAccountChangedOnLoad = false;
accountsManager.NavigateOnAccountChangeAsync().FireAndForget();
}
#endif
}
public async Task DismissRegisterPageAndLogInAsync(string email)
{
await Navigation.PopModalAsync();