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
signIn();
} else if (viewState == ViewState.NO_ACCOUNTS) {
addAccount();
} else if (viewState == ViewState.SIGNIN_AUTH_ERROR) {
updateCredentials();
}
}
......@@ -221,4 +223,13 @@ class AccountPickerBottomSheetMediator implements AccountPickerCoordinator.Liste
}
}.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 {
* Collapses the account list to the selected account.
*/
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);
mContinueAsButton.setVisibility(View.VISIBLE);
mAccountListView.setVisibility(View.GONE);
mSpinnerView.setVisibility(View.GONE);
}
/**
......
......@@ -22,6 +22,12 @@ class AccountPickerBottomSheetViewBinder {
@ViewState
int viewState = model.get(AccountPickerBottomSheetProperties.VIEW_STATE);
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) {
DisplayableProfileData profileData =
model.get(AccountPickerBottomSheetProperties.SELECTED_ACCOUNT_DATA);
......
......@@ -24,6 +24,7 @@ import org.chromium.chrome.browser.signin.WebSigninBridge;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabCreator;
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.GoogleServiceAuthError;
import org.chromium.content_public.browser.LoadUrlParams;
......@@ -37,6 +38,7 @@ import org.chromium.ui.base.WindowAndroid;
*/
public class AccountPickerDelegate implements WebSigninBridge.Listener {
private final WindowAndroid mWindowAndroid;
private final Activity mActivity;
private final Tab mCurrentTab;
private final TabCreator mIncognitoTabCreator;
private final WebSigninBridge.Factory mWebSigninBridgeFactory;
......@@ -49,6 +51,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
TabCreator incognitoTabCreator, WebSigninBridge.Factory webSigninBridgeFactory,
String continueUrl) {
mWindowAndroid = windowAndroid;
mActivity = mWindowAndroid.getActivity().get();
assert mActivity != null : "Activity should not be null!";
mCurrentTab = currentTab;
mIncognitoTabCreator = incognitoTabCreator;
mWebSigninBridgeFactory = webSigninBridgeFactory;
......@@ -62,9 +66,8 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
*/
public IncognitoInterstitialDelegate getIncognitoInterstitialDelegate() {
IncognitoInterstitialDelegate incognitoInterstitialDelegate =
new IncognitoInterstitialDelegate(mWindowAndroid.getActivity().get(),
mIncognitoTabCreator, HelpAndFeedback.getInstance(),
mCurrentTab.getUrlString());
new IncognitoInterstitialDelegate(mActivity, mIncognitoTabCreator,
HelpAndFeedback.getInstance(), mCurrentTab.getUrlString());
return incognitoInterstitialDelegate;
}
......@@ -123,11 +126,21 @@ public class AccountPickerDelegate implements WebSigninBridge.Listener {
} else {
// AccountManagerFacade couldn't create intent, use SigninUtils to open
// 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.
*/
......
......@@ -366,6 +366,34 @@ public class AccountPickerBottomSheetTest {
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
@MediumTest
public void testAddAccountOnExpandedSheet() {
......
......@@ -15,6 +15,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import android.accounts.Account;
import androidx.fragment.app.FragmentActivity;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
......@@ -25,6 +27,7 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.robolectric.Robolectric;
import org.chromium.base.Callback;
import org.chromium.base.test.BaseRobolectricTestRunner;
......@@ -42,6 +45,8 @@ import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.ui.base.WindowAndroid;
import java.lang.ref.WeakReference;
/**
* This class tests the {@link AccountPickerDelegate}.
*/
......@@ -76,6 +81,8 @@ public class AccountPickerDelegateTest {
@Captor
private ArgumentCaptor<LoadUrlParams> mLoadUrlParamsCaptor;
private FragmentActivity mActivity;
private AccountPickerDelegate mDelegate;
private final IdentityManager mIdentityManager =
......@@ -84,6 +91,9 @@ public class AccountPickerDelegateTest {
@Before
public void setUp() {
initMocks(this);
mActivity = Robolectric.setupActivity(FragmentActivity.class);
when(mWindowAndroidMock.getActivity()).thenReturn(new WeakReference<>(mActivity));
Profile.setLastUsedProfileForTesting(mProfileMock);
IdentityServicesProvider.setInstanceForTests(mock(IdentityServicesProvider.class));
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