Commit 88fc1711 authored by Alice Wang's avatar Alice Wang Committed by Commit Bot

[Android][WebSignin] Implement |Sign in again| action for auth error

This CL implements the action of |Sign in again| button on sign-in
auth error page of the web sign-in bottom sheet.

Bug: 1119360
Change-Id: I358efc2e3c9d0d6971b1b5c14f4eebd8e6cb2bb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2379896
Commit-Queue: Alice Wang <aliceywang@chromium.org>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807525}
parent e11c28c2
...@@ -196,6 +196,8 @@ class AccountPickerBottomSheetMediator implements AccountPickerCoordinator.Liste ...@@ -196,6 +196,8 @@ class AccountPickerBottomSheetMediator implements AccountPickerCoordinator.Liste
signIn(); signIn();
} else if (viewState == ViewState.NO_ACCOUNTS) { } else if (viewState == ViewState.NO_ACCOUNTS) {
addAccount(); addAccount();
} else if (viewState == ViewState.SIGNIN_AUTH_ERROR) {
updateCredentials();
} }
} }
...@@ -221,4 +223,13 @@ class AccountPickerBottomSheetMediator implements AccountPickerCoordinator.Liste ...@@ -221,4 +223,13 @@ class AccountPickerBottomSheetMediator implements AccountPickerCoordinator.Liste
} }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
private void updateCredentials() {
mAccountPickerDelegate.updateCredentials(mSelectedAccountName, (isSuccess) -> {
if (isSuccess) {
mModel.set(AccountPickerBottomSheetProperties.VIEW_STATE,
ViewState.COLLAPSED_ACCOUNT_LIST);
}
});
}
} }
...@@ -139,10 +139,15 @@ class AccountPickerBottomSheetView implements BottomSheetContent { ...@@ -139,10 +139,15 @@ class AccountPickerBottomSheetView implements BottomSheetContent {
* Collapses the account list to the selected account. * Collapses the account list to the selected account.
*/ */
void collapseAccountList() { void collapseAccountList() {
mLogoImage.setImageResource(R.drawable.chrome_sync_logo);
mAccountPickerTitle.setText(R.string.signin_account_picker_dialog_title);
mAccountPickerSubtitle.setText(R.string.signin_account_picker_bottom_sheet_subtitle);
mHorizontalDivider.setVisibility(View.VISIBLE);
mSelectedAccountView.setVisibility(View.VISIBLE); mSelectedAccountView.setVisibility(View.VISIBLE);
mContinueAsButton.setVisibility(View.VISIBLE); mContinueAsButton.setVisibility(View.VISIBLE);
mAccountListView.setVisibility(View.GONE); mAccountListView.setVisibility(View.GONE);
mSpinnerView.setVisibility(View.GONE);
} }
/** /**
......
...@@ -22,6 +22,12 @@ class AccountPickerBottomSheetViewBinder { ...@@ -22,6 +22,12 @@ class AccountPickerBottomSheetViewBinder {
@ViewState @ViewState
int viewState = model.get(AccountPickerBottomSheetProperties.VIEW_STATE); int viewState = model.get(AccountPickerBottomSheetProperties.VIEW_STATE);
switchToState(view, viewState); switchToState(view, viewState);
if (viewState == ViewState.COLLAPSED_ACCOUNT_LIST) {
// This is needed when the view state changes from SIGNIN_AUTH_ERROR to
// COLLAPSED_ACCOUNT_LIST
view.updateSelectedAccount(
model.get(AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA));
}
} else if (propertyKey == AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA) { } else if (propertyKey == AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA) {
DisplayableProfileData profileData = DisplayableProfileData profileData =
model.get(AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA); model.get(AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA);
......
...@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.signin.WebSigninBridge; ...@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.signin.WebSigninBridge;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabCreator; import org.chromium.chrome.browser.tabmodel.TabCreator;
import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.AccountUtils;
import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.base.GoogleServiceAuthError; import org.chromium.components.signin.base.GoogleServiceAuthError;
import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.LoadUrlParams;
...@@ -37,6 +38,7 @@ import org.chromium.ui.base.WindowAndroid; ...@@ -37,6 +38,7 @@ import org.chromium.ui.base.WindowAndroid;
*/ */
public class AccountPickerDelegate implements WebSigninBridge.Listener { public class AccountPickerDelegate implements WebSigninBridge.Listener {
private final WindowAndroid mWindowAndroid; private final WindowAndroid mWindowAndroid;
private final Activity mActivity;
private final Tab mCurrentTab; private final Tab mCurrentTab;
private final TabCreator mIncognitoTabCreator; private final TabCreator mIncognitoTabCreator;
private final WebSigninBridge.Factory mWebSigninBridgeFactory; private final WebSigninBridge.Factory mWebSigninBridgeFactory;
...@@ -49,6 +51,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener { ...@@ -49,6 +51,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
TabCreator incognitoTabCreator, WebSigninBridge.Factory webSigninBridgeFactory, TabCreator incognitoTabCreator, WebSigninBridge.Factory webSigninBridgeFactory,
String continueUrl) { String continueUrl) {
mWindowAndroid = windowAndroid; mWindowAndroid = windowAndroid;
mActivity = mWindowAndroid.getActivity().get();
assert mActivity != null : "Activity should not be null!";
mCurrentTab = currentTab; mCurrentTab = currentTab;
mIncognitoTabCreator = incognitoTabCreator; mIncognitoTabCreator = incognitoTabCreator;
mWebSigninBridgeFactory = webSigninBridgeFactory; mWebSigninBridgeFactory = webSigninBridgeFactory;
...@@ -62,9 +66,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener { ...@@ -62,9 +66,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
*/ */
public IncognitoInterstitialDelegate getIncognitoInterstitialDelegate() { public IncognitoInterstitialDelegate getIncognitoInterstitialDelegate() {
IncognitoInterstitialDelegate incognitoInterstitialDelegate = IncognitoInterstitialDelegate incognitoInterstitialDelegate =
new IncognitoInterstitialDelegate(mWindowAndroid.getActivity().get(), new IncognitoInterstitialDelegate(mActivity, mIncognitoTabCreator,
mIncognitoTabCreator, HelpAndFeedback.getInstance(), HelpAndFeedback.getInstance(), mCurrentTab.getUrlString());
mCurrentTab.getUrlString());
return incognitoInterstitialDelegate; return incognitoInterstitialDelegate;
} }
...@@ -123,11 +126,21 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener { ...@@ -123,11 +126,21 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
} else { } else {
// AccountManagerFacade couldn't create intent, use SigninUtils to open // AccountManagerFacade couldn't create intent, use SigninUtils to open
// settings instead. // settings instead.
SigninUtils.openSettingsForAllAccounts(mWindowAndroid.getContext().get()); SigninUtils.openSettingsForAllAccounts(mActivity);
} }
}); });
} }
/**
* Updates credentials of the given account name.
*/
public void updateCredentials(
String accountName, Callback<Boolean> onUpdateCredentialsCallback) {
AccountManagerFacadeProvider.getInstance().updateCredentials(
AccountUtils.createAccountFromName(accountName), mActivity,
onUpdateCredentialsCallback);
}
/** /**
* Sign-in completed successfully and the primary account is available in the cookie jar. * Sign-in completed successfully and the primary account is available in the cookie jar.
*/ */
......
...@@ -366,6 +366,34 @@ public class AccountPickerBottomSheetTest { ...@@ -366,6 +366,34 @@ public class AccountPickerBottomSheetTest {
clickContinueButtonAndCheckSignInInProgressSheet(); clickContinueButtonAndCheckSignInInProgressSheet();
} }
@Test
@MediumTest
public void testSigninAgainButtonOnSigninAuthErrorSheet() {
CoreAccountInfo coreAccountInfo =
mAccountManagerTestRule.toCoreAccountInfo(PROFILE_DATA1.getAccountName());
// Throws an auth error during the sign-in action
doAnswer(invocation -> {
Callback<GoogleServiceAuthError> onSignInErrorCallback = invocation.getArgument(1);
onSignInErrorCallback.onResult(
new GoogleServiceAuthError(State.INVALID_GAIA_CREDENTIALS));
return null;
})
.when(mAccountPickerDelegateMock)
.signIn(eq(coreAccountInfo), any());
buildAndShowCollapsedBottomSheet();
clickContinueButtonAndWaitForErrorSheet();
doAnswer(invocation -> {
Callback<Boolean> callback = invocation.getArgument(1);
callback.onResult(true);
return null;
})
.when(mAccountPickerDelegateMock)
.updateCredentials(eq(PROFILE_DATA1.getAccountName()), any());
onView(withText(R.string.auth_error_card_button)).perform(click());
checkCollapsedAccountList(PROFILE_DATA1);
}
@Test @Test
@MediumTest @MediumTest
public void testAddAccountOnExpandedSheet() { public void testAddAccountOnExpandedSheet() {
......
...@@ -15,6 +15,8 @@ import static org.mockito.MockitoAnnotations.initMocks; ...@@ -15,6 +15,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import android.accounts.Account; import android.accounts.Account;
import androidx.fragment.app.FragmentActivity;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
...@@ -25,6 +27,7 @@ import org.mockito.ArgumentCaptor; ...@@ -25,6 +27,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor; import org.mockito.Captor;
import org.mockito.InOrder; import org.mockito.InOrder;
import org.mockito.Mock; import org.mockito.Mock;
import org.robolectric.Robolectric;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.BaseRobolectricTestRunner;
...@@ -42,6 +45,8 @@ import org.chromium.components.signin.identitymanager.IdentityManager; ...@@ -42,6 +45,8 @@ import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
import java.lang.ref.WeakReference;
/** /**
* This class tests the {@link AccountPickerDelegate}. * This class tests the {@link AccountPickerDelegate}.
*/ */
...@@ -76,6 +81,8 @@ public class AccountPickerDelegateTest { ...@@ -76,6 +81,8 @@ public class AccountPickerDelegateTest {
@Captor @Captor
private ArgumentCaptor<LoadUrlParams> mLoadUrlParamsCaptor; private ArgumentCaptor<LoadUrlParams> mLoadUrlParamsCaptor;
private FragmentActivity mActivity;
private AccountPickerDelegate mDelegate; private AccountPickerDelegate mDelegate;
private final IdentityManager mIdentityManager = private final IdentityManager mIdentityManager =
...@@ -84,6 +91,9 @@ public class AccountPickerDelegateTest { ...@@ -84,6 +91,9 @@ public class AccountPickerDelegateTest {
@Before @Before
public void setUp() { public void setUp() {
initMocks(this); initMocks(this);
mActivity = Robolectric.setupActivity(FragmentActivity.class);
when(mWindowAndroidMock.getActivity()).thenReturn(new WeakReference<>(mActivity));
Profile.setLastUsedProfileForTesting(mProfileMock); Profile.setLastUsedProfileForTesting(mProfileMock);
IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class)); IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class));
when(IdentityServicesProvider.get().getIdentityManager(any())).thenReturn(mIdentityManager); when(IdentityServicesProvider.get().getIdentityManager(any())).thenReturn(mIdentityManager);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment