| Index: chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..96a4915a5de38c466542631ed266446e7a456aa4
|
| --- /dev/null
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunSignInProcessor.java
|
| @@ -0,0 +1,290 @@
|
| +// Copyright 2015 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.firstrun;
|
| +
|
| +import android.accounts.Account;
|
| +import android.app.Activity;
|
| +import android.content.Context;
|
| +import android.os.Bundle;
|
| +import android.preference.PreferenceManager;
|
| +import android.text.TextUtils;
|
| +import android.util.Log;
|
| +
|
| +import org.chromium.base.CommandLine;
|
| +import org.chromium.chrome.ChromeSwitches;
|
| +import org.chromium.chrome.browser.ChromiumApplication;
|
| +import org.chromium.chrome.browser.services.AndroidEduAndChildAccountHelper;
|
| +import org.chromium.chrome.browser.signin.SigninManager;
|
| +import org.chromium.chrome.browser.signin.SigninManager.SignInFlowObserver;
|
| +import org.chromium.chrome.browser.util.FeatureUtilities;
|
| +import org.chromium.sync.signin.AccountManagerHelper;
|
| +import org.chromium.sync.signin.ChromeSigninController;
|
| +
|
| +/**
|
| + * A helper to perform all necessary steps for the automatic FRE sign in.
|
| + * The helper performs:
|
| + * - necessary Android EDU and child account checks;
|
| + * - automatic non-interactive forced sign in for Android EDU and child accounts; and
|
| + * - any pending automatic non-interactive request to sign in from the First Run Experience.
|
| + * The helper calls the observer's onSignInComplete() if
|
| + * - nothing needs to be done, or when
|
| + * - the sign in is complete.
|
| + * If the sign in process fails or if an interactive FRE sequence is necessary,
|
| + * the helper starts the FRE activity, finishes the current activity and calls
|
| + * OnSignInCancelled.
|
| + *
|
| + * Usage:
|
| + * new FirstRunSignInProcessor(activity, shouldShowNotification){
|
| + * override OnSignInComplete and OnSignInCancelled
|
| + * }.start().
|
| + */
|
| +public class FirstRunSignInProcessor {
|
| + /**
|
| + * SharedPreferences preference names to keep the state of the First Run Experience.
|
| + */
|
| + private static final String FIRST_RUN_FLOW_SIGNIN_COMPLETE = "first_run_signin_complete";
|
| + private static final String FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME =
|
| + "first_run_signin_account_name";
|
| + private static final String FIRST_RUN_FLOW_SIGNIN_SETUP_SYNC = "first_run_signin_setup_sync";
|
| +
|
| + private final Activity mActivity;
|
| + private final SigninManager mSignInManager;
|
| + private final SignInFlowObserver mObserver;
|
| + private final boolean mShowSignInNotification;
|
| +
|
| + private boolean mIsAndroidEduDevice;
|
| + private boolean mHasChildAccount;
|
| + private int mSignInType;
|
| +
|
| + /**
|
| + * Initiates the automatic sign-in process in background.
|
| + *
|
| + * @param activity The context for the FRE parameters processor.
|
| + */
|
| + public static void start(Activity activity) {
|
| + new FirstRunSignInProcessor(activity, false, null);
|
| + }
|
| +
|
| + private FirstRunSignInProcessor(Activity activity, boolean showSignInNotification,
|
| + SignInFlowObserver observer) {
|
| + mActivity = activity;
|
| + mSignInManager = SigninManager.get(activity);
|
| + mObserver = observer;
|
| + mShowSignInNotification = showSignInNotification;
|
| +
|
| + new AndroidEduAndChildAccountHelper() {
|
| + @Override
|
| + public void onParametersReady() {
|
| + mIsAndroidEduDevice = isAndroidEduDevice();
|
| + mHasChildAccount = hasChildAccount();
|
| + mSignInManager.onFirstRunCheckDone();
|
| + mSignInType = mHasChildAccount
|
| + ? FirstRunUtil.SIGNIN_TYPE_FORCED_CHILD_ACCOUNT
|
| + : (mIsAndroidEduDevice
|
| + ? FirstRunUtil.SIGNIN_TYPE_FORCED_EDU
|
| + : FirstRunUtil.SIGNIN_TYPE_INTERACTIVE);
|
| +
|
| + // We allow to pass-through without FRE being complete only if
|
| + // - FRE is disabled, or
|
| + // - FRE hasn't been completed, but the user has already seen the ToS in
|
| + // the Setup Wizard.
|
| + boolean firstRunFlowComplete = FirstRunStatus.getFirstRunFlowComplete(mActivity);
|
| + if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE)
|
| + || (!firstRunFlowComplete
|
| + && ToSAckedReceiver.checkAnyUserHasSeenToS(mActivity))) {
|
| + mSignInManager.onFirstRunCheckDone();
|
| + if (mObserver != null) mObserver.onSigninComplete();
|
| + return;
|
| + }
|
| +
|
| + // Otherwise, the FRE must have been completed, so let's force it.
|
| + if (!firstRunFlowComplete) {
|
| + requestToFireIntentAndFinish();
|
| + return;
|
| + }
|
| +
|
| + if (!getFirstRunFlowSignInComplete(mActivity)) {
|
| + // Check if we need to complete any outstanding sign-in requests from FRE.
|
| + // It setFirstRunFlowSignInComplete() once the sign-in is complete or if
|
| + // it's unnecessary.
|
| + completeFreSignInRequest();
|
| + } else {
|
| + processAutomaticSignIn();
|
| + }
|
| + }
|
| + }.start(mActivity);
|
| + }
|
| +
|
| + /**
|
| + * Processes the fully automatic non-FRE-related forced sign-in.
|
| + * This is used to enforce the environment for Android EDU and child accounts.
|
| + */
|
| + private void processAutomaticSignIn() {
|
| + // This is only for non-interactive forced sign-ins.
|
| + assert getFirstRunFlowSignInComplete(mActivity);
|
| + assert !mHasChildAccount || !mIsAndroidEduDevice;
|
| + if (!mIsAndroidEduDevice && !mHasChildAccount) return;
|
| +
|
| + final Account[] googleAccounts =
|
| + AccountManagerHelper.get(mActivity).getGoogleAccounts();
|
| + if (!FeatureUtilities.canAllowSync(mActivity)
|
| + || !SigninManager.get(mActivity.getApplicationContext()).isSignInAllowed()
|
| + || googleAccounts.length != 1) return;
|
| +
|
| + FirstRunUtil.signInToSelectedAccount(mActivity, googleAccounts[0],
|
| + mSignInType, FirstRunUtil.SIGNIN_SYNC_IMMEDIATELY, mShowSignInNotification,
|
| + mObserver);
|
| + }
|
| +
|
| + /**
|
| + * Processes an outstanding FRE sign-in request if any.
|
| + */
|
| + private void completeFreSignInRequest() {
|
| + // This is only for completion of the FRE sign-in process.
|
| + assert !getFirstRunFlowSignInComplete(mActivity);
|
| +
|
| + final String accountName = getFirstRunFlowSignInAccountName(mActivity);
|
| + if (!FeatureUtilities.canAllowSync(mActivity)
|
| + || !SigninManager.get(mActivity.getApplicationContext()).isSignInAllowed()
|
| + || TextUtils.isEmpty(accountName)) {
|
| + setFirstRunFlowSignInComplete(mActivity, true);
|
| + if (mObserver != null) mObserver.onSigninComplete();
|
| + return;
|
| + }
|
| +
|
| + final Account account =
|
| + AccountManagerHelper.get(mActivity).getAccountFromName(accountName);
|
| + if (account == null) {
|
| + // TODO(aruslan): handle the account being removed during the FRE.
|
| + requestToFireIntentAndFinish();
|
| + return;
|
| + }
|
| +
|
| + FirstRunUtil.signInToSelectedAccount(mActivity, account,
|
| + mSignInType, FirstRunUtil.SIGNIN_SYNC_IMMEDIATELY, mShowSignInNotification,
|
| + new SignInFlowObserver() {
|
| + private void completeSignIn() {
|
| + // Show sync settings if user pressed the "Settings" button.
|
| + if (getFirstRunFlowSignInSetupSync(mActivity)) {
|
| + openSyncSettings(
|
| + ChromeSigninController.get(mActivity).getSignedInAccountName());
|
| + }
|
| + setFirstRunFlowSignInComplete(mActivity, true);
|
| + }
|
| +
|
| + @Override
|
| + public void onSigninComplete() {
|
| + completeSignIn();
|
| + if (mObserver != null) mObserver.onSigninComplete();
|
| + }
|
| +
|
| + @Override
|
| + public void onSigninCancelled() {
|
| + completeSignIn();
|
| + if (mObserver != null) mObserver.onSigninCancelled();
|
| + }
|
| + });
|
| + }
|
| +
|
| + /**
|
| + * Opens Sync settings as requested in the FRE sign-in dialog.
|
| + * @param accountName The account to show the sync settings for.
|
| + */
|
| + private void openSyncSettings(final String accountName) {
|
| + ((ChromiumApplication) mActivity.getApplication()).openSyncSettings(accountName);
|
| + }
|
| +
|
| + /**
|
| + * Starts the full FRE and finishes the current activity.
|
| + */
|
| + private void requestToFireIntentAndFinish() {
|
| + Log.e("FirstRunSignInProcessor", "Attempt to pass-through without completed FRE");
|
| + if (mObserver != null) mObserver.onSigninCancelled();
|
| +
|
| + // Things went wrong -- we want the user to go through the full FRE.
|
| + FirstRunStatus.setFirstRunFlowComplete(mActivity, false);
|
| + setFirstRunFlowSignInComplete(mActivity, false);
|
| + setFirstRunFlowSignInAccountName(mActivity, null);
|
| + setFirstRunFlowSignInSetupSync(mActivity, false);
|
| + mActivity.startActivity(FirstRunFlowSequencer.createGenericFirstRunIntent(
|
| + mActivity, mActivity.getIntent(), true));
|
| + }
|
| +
|
| + /**
|
| + * @return Whether there is no pending sign-in requests from the First Run Experience.
|
| + * @param context A context
|
| + */
|
| + private static boolean getFirstRunFlowSignInComplete(Context context) {
|
| + return PreferenceManager.getDefaultSharedPreferences(context)
|
| + .getBoolean(FIRST_RUN_FLOW_SIGNIN_COMPLETE, false);
|
| + }
|
| +
|
| + /**
|
| + * Sets the "pending First Run Experience sign-in requests" preference.
|
| + * @param context A context
|
| + * @param isComplete Whether there is no pending sign-in requests from the First Run Experience.
|
| + */
|
| + private static void setFirstRunFlowSignInComplete(Context context, boolean isComplete) {
|
| + PreferenceManager.getDefaultSharedPreferences(context)
|
| + .edit()
|
| + .putBoolean(FIRST_RUN_FLOW_SIGNIN_COMPLETE, isComplete)
|
| + .apply();
|
| + }
|
| +
|
| + /**
|
| + * @return The account name selected during the First Run Experience, or null if none.
|
| + * @param context A context
|
| + */
|
| + private static String getFirstRunFlowSignInAccountName(Context context) {
|
| + return PreferenceManager.getDefaultSharedPreferences(context)
|
| + .getString(FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, null);
|
| + }
|
| +
|
| + /**
|
| + * Sets the account name for the pending sign-in First Run Experience request.
|
| + * @param context A context
|
| + * @param accountName The account name, or null.
|
| + */
|
| + private static void setFirstRunFlowSignInAccountName(Context context, String accountName) {
|
| + PreferenceManager.getDefaultSharedPreferences(context)
|
| + .edit()
|
| + .putString(FIRST_RUN_FLOW_SIGNIN_ACCOUNT_NAME, accountName)
|
| + .apply();
|
| + }
|
| +
|
| + /**
|
| + * @return Whether the user selected to see the Sync settings once signed in after FRE.
|
| + * @param context A context
|
| + */
|
| + private static boolean getFirstRunFlowSignInSetupSync(Context context) {
|
| + return PreferenceManager.getDefaultSharedPreferences(context)
|
| + .getBoolean(FIRST_RUN_FLOW_SIGNIN_SETUP_SYNC, false);
|
| + }
|
| +
|
| + /**
|
| + * Sets the preference to see the Sync settings once signed in after FRE.
|
| + * @param context A context
|
| + * @param isComplete Whether the user selected to see the Sync settings once signed in.
|
| + */
|
| + private static void setFirstRunFlowSignInSetupSync(Context context, boolean isComplete) {
|
| + PreferenceManager.getDefaultSharedPreferences(context)
|
| + .edit()
|
| + .putBoolean(FIRST_RUN_FLOW_SIGNIN_SETUP_SYNC, isComplete)
|
| + .apply();
|
| + }
|
| +
|
| + /**
|
| + * Finalize the state of the FRE flow (mark is as "complete" and finalize parameters).
|
| + * @param context A context
|
| + * @param data Resulting FRE properties bundle
|
| + */
|
| + public static void finalizeFirstRunFlowState(Context context, Bundle data) {
|
| + FirstRunStatus.setFirstRunFlowComplete(context, true);
|
| + setFirstRunFlowSignInAccountName(context,
|
| + data.getString(FirstRunActivity.RESULT_SIGNIN_ACCOUNT_NAME));
|
| + setFirstRunFlowSignInSetupSync(context,
|
| + data.getBoolean(FirstRunActivity.RESULT_SHOW_SYNC_SETTINGS));
|
| + }
|
| +}
|
|
|