Commit fe0d3033 authored by Boris Sazonov's avatar Boris Sazonov Committed by Commit Bot

[Unity][Android] Show streamlined sign-in screen from sign-in promos

This CL updates personalized sign-in promos to show SigninActivity if
UnifiedConsent feature is enabled. This CL also implements necessary
sign-in flows in SigninFragmentBase and adds corresponding methods
to SigninActivity and SigninFragment.

Bug: 814728
Change-Id: I5d335bcea32834b358d2ca96901ff991691b0fb9
Reviewed-on: https://chromium-review.googlesource.com/1062605Reviewed-by: default avatarBernhard Bauer <bauerb@chromium.org>
Commit-Queue: Boris Sazonov <bsazonov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559491}
parent 57964cb7
......@@ -30,7 +30,7 @@ public class SigninFirstRunFragment extends SigninFragmentBase implements FirstR
String forceAccountTo =
freProperties.getString(AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO);
if (forceAccountTo == null) {
mArguments = createArguments(SigninAccessPoint.START_PAGE);
mArguments = createArguments(SigninAccessPoint.START_PAGE, null);
} else {
@ChildAccountStatus.Status int childAccountStatus =
freProperties.getInt(AccountFirstRunFragment.CHILD_ACCOUNT_STATUS);
......
......@@ -21,13 +21,50 @@ public class SigninActivity extends SynchronousInitializationActivity {
private static final String TAG = "SigninActivity";
/**
* Creates an {@link Intent} which can be used to start the signin flow.
* @param accessPoint {@link AccessPoint} for starting signin flow. Used in metrics.
* Creates an {@link Intent} which can be used to start sign-in flow.
* @param accessPoint {@link AccessPoint} for starting sign-in flow. Used in metrics.
*/
public static Intent createIntent(
Context context, @AccountSigninActivity.AccessPoint int accessPoint) {
return createIntentInternal(context, SigninFragment.createArguments(accessPoint));
}
/**
* Creates an argument bundle to start default 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 Intent createIntentForPromoDefaultFlow(
Context context, @SigninAccessPoint int accessPoint, String accountName) {
return createIntentInternal(context,
SigninFragment.createArgumentsForPromoDefaultFlow(accessPoint, accountName));
}
/**
* 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 Intent createIntentForPromoChooseAccountFlow(
Context context, @SigninAccessPoint int accessPoint, String accountName) {
return createIntentInternal(context,
SigninFragment.createArgumentsForPromoChooseAccountFlow(accessPoint, accountName));
}
/**
* 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 Intent createIntentForPromoAddAccountFlow(
Context context, @SigninAccessPoint int accessPoint) {
return createIntentInternal(
context, SigninFragment.createArgumentsForPromoAddAccountFlow(accessPoint));
}
private static Intent createIntentInternal(Context context, Bundle fragmentArguments) {
Intent intent = new Intent(context, SigninActivity.class);
Bundle fragmentArguments = SigninFragment.createArguments(accessPoint);
intent.putExtras(fragmentArguments);
return intent;
}
......
......@@ -37,22 +37,47 @@ public class SigninFragment extends SigninFragmentBase {
private @PromoAction int mPromoAction;
/**
* Creates an argument bundle to start signin.
* @param accessPoint The access point for starting signin flow.
* 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) {
return SigninFragmentBase.createArguments(accessPoint);
return SigninFragmentBase.createArguments(accessPoint, null);
}
/**
* Creates an argument bundle to start signin from personalized signin promo.
* @param accessPoint The access point for starting signin flow.
* @param promoAction Promo action that was used to start signin. Used for UMA.
* 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 createArgumentsFromPersonalizedPromo(
@SigninAccessPoint int accessPoint, @PromoAction int promoAction) {
Bundle result = SigninFragmentBase.createArguments(accessPoint);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, promoAction);
public static Bundle createArgumentsForPromoDefaultFlow(
@SigninAccessPoint int accessPoint, String accountName) {
Bundle result = SigninFragmentBase.createArguments(accessPoint, accountName);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PROMO_ACTION_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(accessPoint, accountName);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PROMO_ACTION_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(accessPoint);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, PROMO_ACTION_NEW_ACCOUNT);
return result;
}
......@@ -122,7 +147,7 @@ public class SigninFragment extends SigninFragmentBase {
histogram = "Signin.SigninCompletedAccessPoint.NewAccount";
break;
default:
assert false : "Unexpected signin flow type!";
assert false : "Unexpected sign-in flow type!";
return;
}
......@@ -145,7 +170,7 @@ public class SigninFragment extends SigninFragmentBase {
histogram = "Signin.SigninStartedAccessPoint.NewAccount";
break;
default:
assert false : "Unexpected signin flow type!";
assert false : "Unexpected sign-in flow type!";
return;
}
......
......@@ -13,6 +13,7 @@ import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.Fragment;
......@@ -43,6 +44,8 @@ import org.chromium.components.signin.GmsJustUpdatedException;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
......@@ -63,14 +66,24 @@ public abstract class SigninFragmentBase
private static final String ARGUMENT_ACCOUNT_NAME = "SigninFragmentBase.AccountName";
private static final String ARGUMENT_CHILD_ACCOUNT_STATUS =
"SigninFragmentBase.ChildAccountStatus";
private static final String ARGUMENT_SIGNIN_FLOW_TYPE = "SigninFragmentBase.SigninFlowType";
public static final String ACCOUNT_PICKER_DIALOG_TAG =
private static final String ACCOUNT_PICKER_DIALOG_TAG =
"SigninFragmentBase.AccountPickerDialogFragment";
private static final int ADD_ACCOUNT_REQUEST_CODE = 1;
@IntDef({FLOW_DEFAULT, FLOW_FORCED, FLOW_CHOOSE_ACCOUNT, FLOW_ADD_ACCOUNT})
@Retention(RetentionPolicy.SOURCE)
@interface SigninFlowType {}
private static final int FLOW_DEFAULT = 0;
private static final int FLOW_FORCED = 1;
private static final int FLOW_CHOOSE_ACCOUNT = 2;
private static final int FLOW_ADD_ACCOUNT = 3;
private @SigninAccessPoint int mSigninAccessPoint;
private boolean mForceSignin;
private @SigninFlowType int mSigninFlowType;
private @ChildAccountStatus.Status int mChildAccountStatus;
private SigninView mView;
......@@ -97,19 +110,50 @@ public abstract class SigninFragmentBase
private ConfirmSyncDataStateMachine mConfirmSyncDataStateMachine;
/**
* Creates an argument bundle for the default SigninFragmentBase flow (default account will be
* selected, account selection is enabled, etc.).
* @param accessPoint The access point for starting signin flow.
* Creates an argument bundle for the default SigninFragmentBase flow (account selection is
* enabled, etc.).
* @param accessPoint The access point for starting sign-in flow.
* @param accountName The account to preselect or null to preselect the default account.
*/
protected static Bundle createArguments(@SigninAccessPoint int accessPoint) {
protected static Bundle createArguments(
@SigninAccessPoint int accessPoint, @Nullable String accountName) {
Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_DEFAULT);
result.putString(ARGUMENT_ACCOUNT_NAME, accountName);
return result;
}
/**
* Creates an argument bundle for "Choose account" sign-in flow. Account selection dialog will
* be shown at the start of the sign-in process.
* @param accessPoint The access point for starting sign-in flow.
* @param accountName The account to preselect or null to preselect the default account.
*/
protected static Bundle createArgumentsForChooseAccountFlow(
@SigninAccessPoint int accessPoint, @Nullable String accountName) {
Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_CHOOSE_ACCOUNT);
result.putString(ARGUMENT_ACCOUNT_NAME, accountName);
return result;
}
/**
* Creates an argument bundle for "Add account" sign-in flow. Activity to add an account will be
* shown at the start of the sign-in process.
* @param accessPoint The access point for starting sign-in flow.
*/
protected static Bundle createArgumentsForAddAccountFlow(@SigninAccessPoint int accessPoint) {
Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_ADD_ACCOUNT);
return result;
}
/**
* Creates an argument bundle for a custom SigninFragmentBase flow.
* @param accessPoint The access point for starting signin flow.
* @param accessPoint The access point for starting sign-in flow.
* @param accountName The account to preselect.
* @param childAccountStatus Whether the selected account is a child one.
*/
......@@ -117,6 +161,7 @@ public abstract class SigninFragmentBase
String accountName, @ChildAccountStatus.Status int childAccountStatus) {
Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_FORCED);
result.putString(ARGUMENT_ACCOUNT_NAME, accountName);
result.putInt(ARGUMENT_CHILD_ACCOUNT_STATUS, childAccountStatus);
return result;
......@@ -152,7 +197,7 @@ public abstract class SigninFragmentBase
/** Returns whether this fragment is in "force sign-in" mode. */
protected boolean isForcedSignin() {
return mForceSignin;
return mSigninFlowType == FLOW_FORCED;
}
@Override
......@@ -164,12 +209,22 @@ public abstract class SigninFragmentBase
mRequestedAccountName = arguments.getString(ARGUMENT_ACCOUNT_NAME, null);
mChildAccountStatus =
arguments.getInt(ARGUMENT_CHILD_ACCOUNT_STATUS, ChildAccountStatus.NOT_CHILD);
mForceSignin = mRequestedAccountName != null;
mSigninFlowType = arguments.getInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_DEFAULT);
// Don't have a selected account now, onResume will trigger the selection.
// TODO(https://crbug.com/814728): Disable controls until an account is selected.
mAccountSelectionPending = true;
if (savedInstanceState == null) {
// If this fragment is being recreated from a saved state there's no need to show
// account picked or starting AddAccount flow.
if (mSigninFlowType == FLOW_CHOOSE_ACCOUNT) {
showAccountPicker();
} else if (mSigninFlowType == FLOW_ADD_ACCOUNT) {
addAccount();
}
}
mConsentTextTracker = new ConsentTextTracker(getResources());
ProfileDataCache.BadgeConfig badgeConfig = null;
......@@ -233,7 +288,7 @@ public abstract class SigninFragmentBase
});
mView.getScrollView().setScrolledToBottomObserver(this::showAcceptButton);
if (mForceSignin) {
if (isForcedSignin()) {
mView.getAccountPickerEndImageView().setImageResource(
R.drawable.ic_check_googblue_24dp);
mView.getAccountPickerEndImageView().setAlpha(1.0f);
......@@ -533,7 +588,7 @@ public abstract class SigninFragmentBase
}
// Account for forced sign-in flow disappeared before the sign-in was completed.
if (mForceSignin) {
if (isForcedSignin()) {
onSigninRefused();
return;
}
......
......@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.signin;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.support.annotation.DimenRes;
......@@ -18,6 +19,7 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.metrics.ImpressionTracker;
import org.chromium.chrome.browser.metrics.OneShotImpressionListener;
import org.chromium.chrome.browser.signin.AccountSigninActivity.AccessPoint;
......@@ -266,8 +268,14 @@ public class SigninPromoController {
view.getSigninButton().setText(signinButtonText);
view.getSigninButton().setOnClickListener(v -> signinWithDefaultAccount(context));
String chooseAccountButtonText = context.getString(
R.string.signin_promo_choose_account, mProfileData.getAccountName());
final String chooseAccountButtonText;
if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) {
chooseAccountButtonText =
context.getString(R.string.signin_promo_choose_another_account);
} else {
chooseAccountButtonText = context.getString(
R.string.signin_promo_choose_account, mProfileData.getAccountName());
}
view.getChooseAccountButton().setText(chooseAccountButtonText);
view.getChooseAccountButton().setOnClickListener(v -> signinWithNotDefaultAccount(context));
view.getChooseAccountButton().setVisibility(View.VISIBLE);
......@@ -281,22 +289,42 @@ public class SigninPromoController {
private void signinWithNewAccount(Context context) {
recordSigninButtonUsed();
RecordUserAction.record(mSigninNewAccountUserActionName);
context.startActivity(AccountSigninActivity.createIntentForAddAccountSigninFlow(
context, mAccessPoint, true));
final Intent intent;
if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) {
intent = SigninActivity.createIntentForPromoAddAccountFlow(context, mAccessPoint);
} else {
intent = AccountSigninActivity.createIntentForAddAccountSigninFlow(
context, mAccessPoint, true);
}
context.startActivity(intent);
}
private void signinWithDefaultAccount(Context context) {
recordSigninButtonUsed();
RecordUserAction.record(mSigninWithDefaultUserActionName);
context.startActivity(AccountSigninActivity.createIntentForConfirmationOnlySigninFlow(
context, mAccessPoint, mProfileData.getAccountName(), true, true));
final Intent intent;
if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) {
intent = SigninActivity.createIntentForPromoDefaultFlow(
context, mAccessPoint, mProfileData.getAccountName());
} else {
intent = AccountSigninActivity.createIntentForConfirmationOnlySigninFlow(
context, mAccessPoint, mProfileData.getAccountName(), true, true);
}
context.startActivity(intent);
}
private void signinWithNotDefaultAccount(Context context) {
recordSigninButtonUsed();
RecordUserAction.record(mSigninNotDefaultUserActionName);
context.startActivity(AccountSigninActivity.createIntentForDefaultSigninFlow(
context, mAccessPoint, true));
final Intent intent;
if (ChromeFeatureList.isEnabled(ChromeFeatureList.UNIFIED_CONSENT)) {
intent = SigninActivity.createIntentForPromoChooseAccountFlow(
context, mAccessPoint, mProfileData.getAccountName());
} else {
intent = AccountSigninActivity.createIntentForDefaultSigninFlow(
context, mAccessPoint, true);
}
context.startActivity(intent);
}
private void recordSigninButtonUsed() {
......
......@@ -2413,6 +2413,11 @@ Customize this anytime in <ph name="BEGIN_LINK1">&lt;LINK1&gt;</ph>Settings<ph n
<message name="IDS_SIGNIN_PROMO_CHOOSE_ACCOUNT" desc="Button that the user can press if they are not the profile that Chrome found (opposite of 'Continue as Joe Doe').">
Not <ph name="EMAIL">%1$s<ex>john.doe@example.com</ex></ph>?
</message>
<!-- Strings for signin promos when Unified Consent is enabled. -->
<!-- TODO(https://crbug.com/814728): Make translatable when strings are approved. -->
<message name="IDS_SIGNIN_PROMO_CHOOSE_ANOTHER_ACCOUNT" desc="Button that the user can press if they are not the profile that Chrome found (opposite of 'Continue as Joe Doe')." translateable="false">
Choose another account
</message>
<!-- Messages for remote media playback (casting) -->
<message name="IDS_CAST_CASTING_VIDEO" desc="AtHome text to tell user which screen casting is happening. [CHAR LIMIT=40]">
......
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