blob: 2bab8a7f45f12acce82891af3cdd54945158a487 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.signin;
import android.accounts.Account;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.SyncFirstSetupCompleteSource;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.settings.SettingsLauncher;
import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.chrome.browser.sync.settings.ManageSyncSettings;
import org.chromium.chrome.browser.sync.settings.SyncAndServicesSettings;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.AccountUtils;
import org.chromium.components.signin.metrics.SigninAccessPoint;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/** This fragment implements sign-in screen for {@link SigninActivity}. */
public class SigninFragment extends SigninFragmentBase {
private static final String TAG = "SigninFragment";
private static final String ARGUMENT_ACCESS_POINT = "SigninFragment.AccessPoint";
private static final String ARGUMENT_PERSONALIZED_PROMO_ACTION =
"SigninFragment.PersonalizedPromoAction";
@IntDef({PromoAction.NONE, PromoAction.WITH_DEFAULT, PromoAction.NOT_DEFAULT,
PromoAction.NEW_ACCOUNT})
@Retention(RetentionPolicy.SOURCE)
public @interface PromoAction {
int NONE = 0;
int WITH_DEFAULT = 1;
int NOT_DEFAULT = 2;
int NEW_ACCOUNT = 3;
}
private @SigninAccessPoint int mSigninAccessPoint;
private @PromoAction int mPromoAction;
/**
* Creates an argument bundle to start sign-in.
* @param accessPoint The access point for starting sign-in flow.
*/
public static Bundle createArguments(@SigninAccessPoint int accessPoint) {
Bundle result = SigninFragmentBase.createArguments(null);
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
return result;
}
/**
* Creates an argument bundle to start sign-in from personalized sign-in promo.
* @param accessPoint The access point for starting sign-in flow.
* @param accountName The account to preselect or null to preselect the default account.
*/
public static Bundle createArgumentsForPromoDefaultFlow(
@SigninAccessPoint int accessPoint, String accountName) {
Bundle result = SigninFragmentBase.createArguments(accountName);
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PromoAction.WITH_DEFAULT);
return result;
}
/**
* Creates an argument bundle to start "Choose account" sign-in flow from personalized sign-in
* promo.
* @param accessPoint The access point for starting sign-in flow.
* @param accountName The account to preselect or null to preselect the default account.
*/
public static Bundle createArgumentsForPromoChooseAccountFlow(
@SigninAccessPoint int accessPoint, String accountName) {
Bundle result = SigninFragmentBase.createArgumentsForChooseAccountFlow(accountName);
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PromoAction.NOT_DEFAULT);
return result;
}
/**
* Creates an argument bundle to start "New account" sign-in flow from personalized sign-in
* promo.
* @param accessPoint The access point for starting sign-in flow.
*/
public static Bundle createArgumentsForPromoAddAccountFlow(@SigninAccessPoint int accessPoint) {
Bundle result = SigninFragmentBase.createArgumentsForAddAccountFlow();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PromoAction.NEW_ACCOUNT);
return result;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int accessPoint = getSigninArguments().getInt(ARGUMENT_ACCESS_POINT, -1);
assert accessPoint == SigninAccessPoint.AUTOFILL_DROPDOWN
|| accessPoint == SigninAccessPoint.BOOKMARK_MANAGER
|| accessPoint == SigninAccessPoint.NTP_CONTENT_SUGGESTIONS
|| accessPoint == SigninAccessPoint.RECENT_TABS
|| accessPoint == SigninAccessPoint.SETTINGS
|| accessPoint
== SigninAccessPoint.SIGNIN_PROMO : "invalid access point: " + accessPoint;
mSigninAccessPoint = accessPoint;
mPromoAction =
getSigninArguments().getInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PromoAction.NONE);
SigninManager.logSigninStartAccessPoint(mSigninAccessPoint);
recordSigninStartedHistogramAccountInfo();
recordSigninStartedUserAction();
}
@Override
protected Bundle getSigninArguments() {
return getArguments();
}
@Override
protected void onSigninRefused() {
getActivity().finish();
}
@Override
protected void onSigninAccepted(String accountName, boolean isDefaultAccount,
boolean settingsClicked, Runnable callback) {
// TODO(https://crbug.com/1002056): Change onSigninAccepted to get CoreAccountInfo.
Account account = AccountUtils.findAccountByName(
AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(), accountName);
if (account == null) {
callback.run();
return;
}
SigninManager signinManager = IdentityServicesProvider.get().getSigninManager(
Profile.getLastUsedRegularProfile());
signinManager.signIn(
mSigninAccessPoint, account, new SigninManager.SignInCallback() {
@Override
public void onSignInComplete() {
UnifiedConsentServiceBridge.setUrlKeyedAnonymizedDataCollectionEnabled(
Profile.getLastUsedRegularProfile(), true);
SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
if (settingsClicked) {
if (ChromeFeatureList.isEnabled(
ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) {
settingsLauncher.launchSettingsActivity(getActivity(),
ManageSyncSettings.class,
ManageSyncSettings.createArguments(true));
} else {
settingsLauncher.launchSettingsActivity(getActivity(),
SyncAndServicesSettings.class,
SyncAndServicesSettings.createArguments(true));
}
} else {
ProfileSyncService.get().setFirstSetupComplete(
SyncFirstSetupCompleteSource.BASIC_FLOW);
}
recordSigninCompletedHistogramAccountInfo();
Activity activity = getActivity();
if (activity != null) activity.finish();
callback.run();
}
@Override
public void onSignInAborted() {
callback.run();
}
});
}
@Override
protected int getNegativeButtonTextId() {
return mSigninAccessPoint == SigninAccessPoint.SIGNIN_PROMO ? R.string.no_thanks
: R.string.cancel;
}
private void recordSigninCompletedHistogramAccountInfo() {
final String histogram;
switch (mPromoAction) {
case PromoAction.NONE:
return;
case PromoAction.WITH_DEFAULT:
histogram = "Signin.SigninCompletedAccessPoint.WithDefault";
break;
case PromoAction.NOT_DEFAULT:
histogram = "Signin.SigninCompletedAccessPoint.NotDefault";
break;
case PromoAction.NEW_ACCOUNT:
// On Android, the promo does not have a button to add an account when there is
// already an account on the device. That flow goes through the NotDefault promo
// instead. Always use the NoExistingAccount variant.
histogram = "Signin.SigninCompletedAccessPoint.NewAccountNoExistingAccount";
break;
default:
assert false : "Unexpected sign-in flow type!";
return;
}
RecordHistogram.recordEnumeratedHistogram(
histogram, mSigninAccessPoint, SigninAccessPoint.MAX);
}
private void recordSigninStartedHistogramAccountInfo() {
final String histogram;
switch (mPromoAction) {
case PromoAction.NONE:
return;
case PromoAction.WITH_DEFAULT:
histogram = "Signin.SigninStartedAccessPoint.WithDefault";
break;
case PromoAction.NOT_DEFAULT:
histogram = "Signin.SigninStartedAccessPoint.NotDefault";
break;
case PromoAction.NEW_ACCOUNT:
// On Android, the promo does not have a button to add an account when there is
// already an account on the device. That flow goes through the NotDefault promo
// instead. Always use the NoExistingAccount variant.
histogram = "Signin.SigninStartedAccessPoint.NewAccountNoExistingAccount";
break;
default:
assert false : "Unexpected sign-in flow type!";
return;
}
RecordHistogram.recordEnumeratedHistogram(
histogram, mSigninAccessPoint, SigninAccessPoint.MAX);
}
private void recordSigninStartedUserAction() {
switch (mSigninAccessPoint) {
case SigninAccessPoint.AUTOFILL_DROPDOWN:
RecordUserAction.record("Signin_Signin_FromAutofillDropdown");
break;
case SigninAccessPoint.BOOKMARK_MANAGER:
RecordUserAction.record("Signin_Signin_FromBookmarkManager");
break;
case SigninAccessPoint.RECENT_TABS:
RecordUserAction.record("Signin_Signin_FromRecentTabs");
break;
case SigninAccessPoint.SETTINGS:
RecordUserAction.record("Signin_Signin_FromSettings");
break;
case SigninAccessPoint.SIGNIN_PROMO:
RecordUserAction.record("Signin_Signin_FromSigninPromo");
break;
case SigninAccessPoint.NTP_CONTENT_SUGGESTIONS:
RecordUserAction.record("Signin_Signin_FromNTPContentSuggestions");
break;
default:
assert false : "Invalid access point.";
}
}
}