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 ...@@ -30,7 +30,7 @@ public class SigninFirstRunFragment extends SigninFragmentBase implements FirstR
String forceAccountTo = String forceAccountTo =
freProperties.getString(AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO); freProperties.getString(AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO);
if (forceAccountTo == null) { if (forceAccountTo == null) {
mArguments = createArguments(SigninAccessPoint.START_PAGE); mArguments = createArguments(SigninAccessPoint.START_PAGE, null);
} else { } else {
@ChildAccountStatus.Status int childAccountStatus = @ChildAccountStatus.Status int childAccountStatus =
freProperties.getInt(AccountFirstRunFragment.CHILD_ACCOUNT_STATUS); freProperties.getInt(AccountFirstRunFragment.CHILD_ACCOUNT_STATUS);
......
...@@ -21,13 +21,50 @@ public class SigninActivity extends SynchronousInitializationActivity { ...@@ -21,13 +21,50 @@ public class SigninActivity extends SynchronousInitializationActivity {
private static final String TAG = "SigninActivity"; private static final String TAG = "SigninActivity";
/** /**
* Creates an {@link Intent} which can be used to start the signin flow. * Creates an {@link Intent} which can be used to start sign-in flow.
* @param accessPoint {@link AccessPoint} for starting signin flow. Used in metrics. * @param accessPoint {@link AccessPoint} for starting sign-in flow. Used in metrics.
*/ */
public static Intent createIntent( public static Intent createIntent(
Context context, @AccountSigninActivity.AccessPoint int accessPoint) { 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); Intent intent = new Intent(context, SigninActivity.class);
Bundle fragmentArguments = SigninFragment.createArguments(accessPoint);
intent.putExtras(fragmentArguments); intent.putExtras(fragmentArguments);
return intent; return intent;
} }
......
...@@ -37,22 +37,47 @@ public class SigninFragment extends SigninFragmentBase { ...@@ -37,22 +37,47 @@ public class SigninFragment extends SigninFragmentBase {
private @PromoAction int mPromoAction; private @PromoAction int mPromoAction;
/** /**
* Creates an argument bundle to start signin. * Creates an argument bundle to start sign-in.
* @param accessPoint The access point for starting signin flow. * @param accessPoint The access point for starting sign-in flow.
*/ */
public static Bundle createArguments(@SigninAccessPoint int accessPoint) { 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. * Creates an argument bundle to start sign-in from personalized sign-in promo.
* @param accessPoint The access point for starting signin flow. * @param accessPoint The access point for starting sign-in flow.
* @param promoAction Promo action that was used to start signin. Used for UMA. * @param accountName The account to preselect or null to preselect the default account.
*/ */
public static Bundle createArgumentsFromPersonalizedPromo( public static Bundle createArgumentsForPromoDefaultFlow(
@SigninAccessPoint int accessPoint, @PromoAction int promoAction) { @SigninAccessPoint int accessPoint, String accountName) {
Bundle result = SigninFragmentBase.createArguments(accessPoint); Bundle result = SigninFragmentBase.createArguments(accessPoint, accountName);
result.putInt(ARGUMENT_PERSONALIZED_PROMO_ACTION, promoAction); 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; return result;
} }
...@@ -122,7 +147,7 @@ public class SigninFragment extends SigninFragmentBase { ...@@ -122,7 +147,7 @@ public class SigninFragment extends SigninFragmentBase {
histogram = "Signin.SigninCompletedAccessPoint.NewAccount"; histogram = "Signin.SigninCompletedAccessPoint.NewAccount";
break; break;
default: default:
assert false : "Unexpected signin flow type!"; assert false : "Unexpected sign-in flow type!";
return; return;
} }
...@@ -145,7 +170,7 @@ public class SigninFragment extends SigninFragmentBase { ...@@ -145,7 +170,7 @@ public class SigninFragment extends SigninFragmentBase {
histogram = "Signin.SigninStartedAccessPoint.NewAccount"; histogram = "Signin.SigninStartedAccessPoint.NewAccount";
break; break;
default: default:
assert false : "Unexpected signin flow type!"; assert false : "Unexpected sign-in flow type!";
return; return;
} }
......
...@@ -13,6 +13,7 @@ import android.graphics.Point; ...@@ -13,6 +13,7 @@ import android.graphics.Point;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.SystemClock; import android.os.SystemClock;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.StringRes; import android.support.annotation.StringRes;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
...@@ -43,6 +44,8 @@ import org.chromium.components.signin.GmsJustUpdatedException; ...@@ -43,6 +44,8 @@ import org.chromium.components.signin.GmsJustUpdatedException;
import org.chromium.ui.text.NoUnderlineClickableSpan; import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier; import org.chromium.ui.text.SpanApplier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -63,14 +66,24 @@ public abstract class SigninFragmentBase ...@@ -63,14 +66,24 @@ public abstract class SigninFragmentBase
private static final String ARGUMENT_ACCOUNT_NAME = "SigninFragmentBase.AccountName"; private static final String ARGUMENT_ACCOUNT_NAME = "SigninFragmentBase.AccountName";
private static final String ARGUMENT_CHILD_ACCOUNT_STATUS = private static final String ARGUMENT_CHILD_ACCOUNT_STATUS =
"SigninFragmentBase.ChildAccountStatus"; "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"; "SigninFragmentBase.AccountPickerDialogFragment";
private static final int ADD_ACCOUNT_REQUEST_CODE = 1; 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 @SigninAccessPoint int mSigninAccessPoint;
private boolean mForceSignin; private @SigninFlowType int mSigninFlowType;
private @ChildAccountStatus.Status int mChildAccountStatus; private @ChildAccountStatus.Status int mChildAccountStatus;
private SigninView mView; private SigninView mView;
...@@ -97,19 +110,50 @@ public abstract class SigninFragmentBase ...@@ -97,19 +110,50 @@ public abstract class SigninFragmentBase
private ConfirmSyncDataStateMachine mConfirmSyncDataStateMachine; private ConfirmSyncDataStateMachine mConfirmSyncDataStateMachine;
/** /**
* Creates an argument bundle for the default SigninFragmentBase flow (default account will be * Creates an argument bundle for the default SigninFragmentBase flow (account selection is
* selected, account selection is enabled, etc.). * enabled, etc.).
* @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 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(); Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint); 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; return result;
} }
/** /**
* Creates an argument bundle for a custom SigninFragmentBase flow. * 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 accountName The account to preselect.
* @param childAccountStatus Whether the selected account is a child one. * @param childAccountStatus Whether the selected account is a child one.
*/ */
...@@ -117,6 +161,7 @@ public abstract class SigninFragmentBase ...@@ -117,6 +161,7 @@ public abstract class SigninFragmentBase
String accountName, @ChildAccountStatus.Status int childAccountStatus) { String accountName, @ChildAccountStatus.Status int childAccountStatus) {
Bundle result = new Bundle(); Bundle result = new Bundle();
result.putInt(ARGUMENT_ACCESS_POINT, accessPoint); result.putInt(ARGUMENT_ACCESS_POINT, accessPoint);
result.putInt(ARGUMENT_SIGNIN_FLOW_TYPE, FLOW_FORCED);
result.putString(ARGUMENT_ACCOUNT_NAME, accountName); result.putString(ARGUMENT_ACCOUNT_NAME, accountName);
result.putInt(ARGUMENT_CHILD_ACCOUNT_STATUS, childAccountStatus); result.putInt(ARGUMENT_CHILD_ACCOUNT_STATUS, childAccountStatus);
return result; return result;
...@@ -152,7 +197,7 @@ public abstract class SigninFragmentBase ...@@ -152,7 +197,7 @@ public abstract class SigninFragmentBase
/** Returns whether this fragment is in "force sign-in" mode. */ /** Returns whether this fragment is in "force sign-in" mode. */
protected boolean isForcedSignin() { protected boolean isForcedSignin() {
return mForceSignin; return mSigninFlowType == FLOW_FORCED;
} }
@Override @Override
...@@ -164,12 +209,22 @@ public abstract class SigninFragmentBase ...@@ -164,12 +209,22 @@ public abstract class SigninFragmentBase
mRequestedAccountName = arguments.getString(ARGUMENT_ACCOUNT_NAME, null); mRequestedAccountName = arguments.getString(ARGUMENT_ACCOUNT_NAME, null);
mChildAccountStatus = mChildAccountStatus =
arguments.getInt(ARGUMENT_CHILD_ACCOUNT_STATUS, ChildAccountStatus.NOT_CHILD); 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. // Don't have a selected account now, onResume will trigger the selection.
// TODO(https://crbug.com/814728): Disable controls until an account is selected. // TODO(https://crbug.com/814728): Disable controls until an account is selected.
mAccountSelectionPending = true; 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()); mConsentTextTracker = new ConsentTextTracker(getResources());
ProfileDataCache.BadgeConfig badgeConfig = null; ProfileDataCache.BadgeConfig badgeConfig = null;
...@@ -233,7 +288,7 @@ public abstract class SigninFragmentBase ...@@ -233,7 +288,7 @@ public abstract class SigninFragmentBase
}); });
mView.getScrollView().setScrolledToBottomObserver(this::showAcceptButton); mView.getScrollView().setScrolledToBottomObserver(this::showAcceptButton);
if (mForceSignin) { if (isForcedSignin()) {
mView.getAccountPickerEndImageView().setImageResource( mView.getAccountPickerEndImageView().setImageResource(
R.drawable.ic_check_googblue_24dp); R.drawable.ic_check_googblue_24dp);
mView.getAccountPickerEndImageView().setAlpha(1.0f); mView.getAccountPickerEndImageView().setAlpha(1.0f);
...@@ -533,7 +588,7 @@ public abstract class SigninFragmentBase ...@@ -533,7 +588,7 @@ public abstract class SigninFragmentBase
} }
// Account for forced sign-in flow disappeared before the sign-in was completed. // Account for forced sign-in flow disappeared before the sign-in was completed.
if (mForceSignin) { if (isForcedSignin()) {
onSigninRefused(); onSigninRefused();
return; return;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package org.chromium.chrome.browser.signin; package org.chromium.chrome.browser.signin;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.annotation.DimenRes; import android.support.annotation.DimenRes;
...@@ -18,6 +19,7 @@ import org.chromium.base.VisibleForTesting; ...@@ -18,6 +19,7 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.metrics.ImpressionTracker; import org.chromium.chrome.browser.metrics.ImpressionTracker;
import org.chromium.chrome.browser.metrics.OneShotImpressionListener; import org.chromium.chrome.browser.metrics.OneShotImpressionListener;
import org.chromium.chrome.browser.signin.AccountSigninActivity.AccessPoint; import org.chromium.chrome.browser.signin.AccountSigninActivity.AccessPoint;
...@@ -266,8 +268,14 @@ public class SigninPromoController { ...@@ -266,8 +268,14 @@ public class SigninPromoController {
view.getSigninButton().setText(signinButtonText); view.getSigninButton().setText(signinButtonText);
view.getSigninButton().setOnClickListener(v -> signinWithDefaultAccount(context)); view.getSigninButton().setOnClickListener(v -> signinWithDefaultAccount(context));
String chooseAccountButtonText = context.getString( final String chooseAccountButtonText;
R.string.signin_promo_choose_account, mProfileData.getAccountName()); 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().setText(chooseAccountButtonText);
view.getChooseAccountButton().setOnClickListener(v -> signinWithNotDefaultAccount(context)); view.getChooseAccountButton().setOnClickListener(v -> signinWithNotDefaultAccount(context));
view.getChooseAccountButton().setVisibility(View.VISIBLE); view.getChooseAccountButton().setVisibility(View.VISIBLE);
...@@ -281,22 +289,42 @@ public class SigninPromoController { ...@@ -281,22 +289,42 @@ public class SigninPromoController {
private void signinWithNewAccount(Context context) { private void signinWithNewAccount(Context context) {
recordSigninButtonUsed(); recordSigninButtonUsed();
RecordUserAction.record(mSigninNewAccountUserActionName); RecordUserAction.record(mSigninNewAccountUserActionName);
context.startActivity(AccountSigninActivity.createIntentForAddAccountSigninFlow( final Intent intent;
context, mAccessPoint, true)); 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) { private void signinWithDefaultAccount(Context context) {
recordSigninButtonUsed(); recordSigninButtonUsed();
RecordUserAction.record(mSigninWithDefaultUserActionName); RecordUserAction.record(mSigninWithDefaultUserActionName);
context.startActivity(AccountSigninActivity.createIntentForConfirmationOnlySigninFlow( final Intent intent;
context, mAccessPoint, mProfileData.getAccountName(), true, true)); 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) { private void signinWithNotDefaultAccount(Context context) {
recordSigninButtonUsed(); recordSigninButtonUsed();
RecordUserAction.record(mSigninNotDefaultUserActionName); RecordUserAction.record(mSigninNotDefaultUserActionName);
context.startActivity(AccountSigninActivity.createIntentForDefaultSigninFlow( final Intent intent;
context, mAccessPoint, true)); 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() { private void recordSigninButtonUsed() {
......
...@@ -2413,6 +2413,11 @@ Customize this anytime in <ph name="BEGIN_LINK1">&lt;LINK1&gt;</ph>Settings<ph n ...@@ -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')."> <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>? Not <ph name="EMAIL">%1$s<ex>john.doe@example.com</ex></ph>?
</message> </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) --> <!-- 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]"> <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