Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(740)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java

Issue 1574273002: Unify and Improve the Sign-In and Sync Confirmation Screens on Clank. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java
index 002cd2eb946942ef81e43055575cba6d9ebd08e5..856c7d2bc0fc791d629afc0c546085aad5b44c80 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/AccountFirstRunView.java
@@ -6,11 +6,13 @@ package org.chromium.chrome.browser.firstrun;
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.Color;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.text.TextPaint;
import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
import android.util.AttributeSet;
-import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -27,7 +29,8 @@ import org.chromium.chrome.browser.firstrun.ImageCarousel.ImageCarouselPositionC
import org.chromium.chrome.browser.profiles.ProfileDownloader;
import org.chromium.chrome.browser.signin.SigninManager;
import org.chromium.sync.signin.AccountManagerHelper;
-import org.chromium.ui.widget.ButtonCompat;
+import org.chromium.ui.text.SpanApplier;
+import org.chromium.ui.text.SpanApplier.SpanInfo;
import java.util.List;
@@ -45,12 +48,6 @@ public class AccountFirstRunView extends FrameLayout
*/
public interface Listener {
/**
- * The user selected an account.
- * @param accountName The name of the account
- */
- public void onAccountSelectionConfirmed(String accountName);
-
- /**
* The user canceled account selection.
*/
public void onAccountSelectionCanceled();
@@ -61,16 +58,24 @@ public class AccountFirstRunView extends FrameLayout
public void onNewAccount();
/**
- * The user has been signed in and pressed 'Done' button.
+ * The user selected an account.
+ * This call will be followed by either {@link #onSettingsClicked} or
+ * {@link #onDoneClicked}.
* @param accountName The name of the account
*/
- public void onSigningInCompleted(String accountName);
+ public void onAccountSelected(String accountName);
/**
- * The user has signed in and pressed 'Settings' button.
- * @param accountName The name of the account
+ * The user has completed the dialog flow.
+ * This will only be called after {@link #onAccountSelected} and should exit the View.
*/
- public void onSettingsButtonClicked(String accountName);
+ public void onDoneClicked();
+
+ /**
+ * The user has selected to view sync settings.
+ * This will only be called after {@link #onAccountSelected} and should exit the View.
+ */
+ public void onSettingsClicked();
/**
* Failed to set the forced account because it wasn't found.
@@ -102,20 +107,27 @@ public class AccountFirstRunView extends FrameLayout
}
}
+ private static final String TAG = "AccountFirstRunView";
+
private static final int EXPERIMENT_TITLE_VARIANT_MASK = 1;
private static final int EXPERIMENT_SUMMARY_VARIANT_MASK = 2;
private static final int EXPERIMENT_LAYOUT_VARIANT_MASK = 4;
private static final int EXPERIMENT_MAX_VALUE = 7;
+ private static final String SETTINGS_LINK_OPEN = "<LINK1>";
+ private static final String SETTINGS_LINK_CLOSE = "</LINK1>";
+
private AccountManagerHelper mAccountManagerHelper;
private List<String> mAccountNames;
private ArrayAdapter<CharSequence> mArrayAdapter;
private ImageCarousel mImageCarousel;
private Button mPositiveButton;
private Button mNegativeButton;
+ private TextView mTitle;
private TextView mDescriptionText;
private Listener mListener;
private Spinner mSpinner;
+ private Drawable mSpinnerBackground;
private String mForcedAccountName;
private String mAccountName;
private String mAddAnotherAccount;
@@ -123,11 +135,14 @@ public class AccountFirstRunView extends FrameLayout
private boolean mSignedIn;
private boolean mPositionSetProgrammatically;
private int mDescriptionTextId;
+ private int mCancelButtonTextId;
private boolean mIsChildAccount;
private boolean mHorizontalModeEnabled = true;
+ private boolean mShowSettingsSpan = true;
public AccountFirstRunView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mAccountManagerHelper = AccountManagerHelper.get(getContext().getApplicationContext());
}
/**
@@ -157,30 +172,32 @@ public class AccountFirstRunView extends FrameLayout
mPositiveButton = (Button) findViewById(R.id.positive_button);
mNegativeButton = (Button) findViewById(R.id.negative_button);
- mNegativeButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- setButtonsEnabled(false);
- mListener.onAccountSelectionCanceled();
- }
- });
// A workaround for Android support library ignoring padding set in XML. b/20307607
int padding = getResources().getDimensionPixelSize(R.dimen.fre_button_padding);
ApiCompatibilityUtils.setPaddingRelative(mPositiveButton, padding, 0, padding, 0);
ApiCompatibilityUtils.setPaddingRelative(mNegativeButton, padding, 0, padding, 0);
+ mTitle = (TextView) findViewById(R.id.title);
mDescriptionText = (TextView) findViewById(R.id.description);
+ // For the spans to be clickable.
+ mDescriptionText.setMovementMethod(LinkMovementMethod.getInstance());
mDescriptionTextId = R.string.fre_account_choice_description;
+ // TODO(peconn): Ensure this is changed to R.string.cancel when used in Settings > Sign In.
+ mCancelButtonTextId = R.string.fre_skip_text;
+
+ // Set the invisible TextView to contain the longest text the visible TextView can hold.
+ // It assumes that the signed in description for child accounts is the longest text.
+ ((TextView) findViewById(R.id.longest_description)).setText(getSignedInDescription(true));
+
mAddAnotherAccount = getResources().getString(R.string.fre_add_account);
mSpinner = (Spinner) findViewById(R.id.google_accounts_spinner);
+ mSpinnerBackground = mSpinner.getBackground();
mArrayAdapter = new ArrayAdapter<CharSequence>(
getContext().getApplicationContext(), R.layout.fre_spinner_text);
- updateAccounts();
-
mArrayAdapter.setDropDownViewResource(R.layout.fre_spinner_dropdown);
mSpinner.setAdapter(mArrayAdapter);
mSpinner.setOnItemSelectedListener(new SpinnerOnItemSelectedListener());
@@ -201,6 +218,8 @@ public class AccountFirstRunView extends FrameLayout
return super.performAccessibilityAction(host, action, args);
}
});
+
+ showSignInPage();
}
@Override
@@ -213,7 +232,12 @@ public class AccountFirstRunView extends FrameLayout
public void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == View.VISIBLE) {
- updateAccounts();
+ if (updateAccounts()) {
+ // A new account has been added and the visibility has returned to us.
+ // The updateAccounts function will have selected the new account.
+ // Shortcut to confirm sign in page.
+ showConfirmSignInPage();
+ }
}
}
@@ -244,33 +268,20 @@ public class AccountFirstRunView extends FrameLayout
/**
* Changes the visuals slightly for when this view appears in the recent tabs page instead of
* in first run. For example, the title text is changed as well as the button style.
+ * This is currently used in the Recent Tabs Promo and the Enhanced Bookmark page.
*/
- public void configureForRecentTabsPage() {
+ public void configureForRecentTabsOrBookmarksPage() {
mHorizontalModeEnabled = false;
+ mShowSettingsSpan = false;
setBackgroundResource(R.color.ntp_bg);
- TextView title = (TextView) findViewById(R.id.title);
- title.setText(R.string.sign_in_to_chrome);
+ mTitle.setText(R.string.sign_in_to_chrome);
- // Remove the border above the button, swap in a new button with a blue material background,
- // and center the button.
- View buttonBarSeparator = findViewById(R.id.button_bar_separator);
- buttonBarSeparator.setVisibility(View.GONE);
+ mCancelButtonTextId = R.string.cancel;
+ setUpCancelButton();
- LinearLayout buttonContainer = (LinearLayout) findViewById(R.id.button_bar);
- buttonContainer.setGravity(Gravity.CENTER_HORIZONTAL);
- setPadding(0, 0, 0, getResources().getDimensionPixelOffset(
- R.dimen.sign_in_promo_padding_bottom));
-
- ButtonCompat positiveButton = new ButtonCompat(getContext(),
- ApiCompatibilityUtils.getColor(getResources(), R.color.light_active_color));
- positiveButton.setTextColor(Color.WHITE);
- positiveButton.setLayoutParams(new LinearLayout.LayoutParams(
- LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
-
- buttonContainer.removeView(mPositiveButton);
- buttonContainer.addView(positiveButton);
- mPositiveButton = positiveButton;
+ setPadding(0, 0, 0,
+ getResources().getDimensionPixelOffset(R.dimen.sign_in_promo_padding_bottom));
}
/**
@@ -281,9 +292,8 @@ public class AccountFirstRunView extends FrameLayout
int experimentGroup = SigninManager.getAndroidSigninPromoExperimentGroup();
assert experimentGroup >= 0 && experimentGroup <= EXPERIMENT_MAX_VALUE;
- TextView title = (TextView) findViewById(R.id.title);
if ((experimentGroup & EXPERIMENT_TITLE_VARIANT_MASK) != 0) {
- title.setText(R.string.make_chrome_yours);
+ mTitle.setText(R.string.make_chrome_yours);
}
mDescriptionTextId = (experimentGroup & EXPERIMENT_SUMMARY_VARIANT_MASK) != 0
@@ -322,36 +332,21 @@ public class AccountFirstRunView extends FrameLayout
}
/**
- * Tell the view whether or not the user can cancel account selection. In
- * wizards, it makes sense to allow the user to skip account selection.
- * However, in other settings-type contexts it does not make sense to allow
- * this.
- *
- * @param canCancel Whether or not account selection can be canceled.
- */
- public void setCanCancel(boolean canCancel) {
- mNegativeButton.setVisibility(canCancel ? View.VISIBLE : View.GONE);
- mPositiveButton.setGravity(
- canCancel ? Gravity.END | Gravity.CENTER_VERTICAL : Gravity.CENTER);
- }
-
- /**
* Refresh the list of available system account.
+ * @return Whether any new accounts were added (the first newly added account will now be
+ * selected).
*/
- private void updateAccounts() {
- if (mSignedIn) return;
- setButtonsEnabled(true);
-
- mAccountManagerHelper = AccountManagerHelper.get(getContext().getApplicationContext());
+ private boolean updateAccounts() {
+ if (mSignedIn) return false;
List<String> oldAccountNames = mAccountNames;
mAccountNames = mAccountManagerHelper.getGoogleAccountNames();
int accountToSelect = 0;
- if (mForcedAccountName != null) {
+ if (isInForcedAccountMode()) {
accountToSelect = mAccountNames.indexOf(mForcedAccountName);
if (accountToSelect < 0) {
mListener.onFailedToSetForcedAccount(mForcedAccountName);
- return;
+ return false;
}
} else {
accountToSelect = getIndexOfNewElement(
@@ -363,24 +358,14 @@ public class AccountFirstRunView extends FrameLayout
mSpinner.setVisibility(View.VISIBLE);
mArrayAdapter.addAll(mAccountNames);
mArrayAdapter.add(mAddAnotherAccount);
- mPositiveButton.setText(R.string.choose_account_sign_in);
- mPositiveButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mListener.onAccountSelectionConfirmed(mAccountName);
- }
- });
+
+ setUpSignInButton(true);
mDescriptionText.setText(mDescriptionTextId);
+
} else {
mSpinner.setVisibility(View.GONE);
mArrayAdapter.add(mAddAnotherAccount);
- mPositiveButton.setText(R.string.fre_no_accounts);
- mPositiveButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mListener.onNewAccount();
- }
- });
+ setUpSignInButton(false);
mDescriptionText.setText(R.string.fre_no_account_choice_description);
}
@@ -390,6 +375,10 @@ public class AccountFirstRunView extends FrameLayout
mSpinner.setSelection(accountToSelect);
mAccountName = mArrayAdapter.getItem(accountToSelect).toString();
mImageCarousel.scrollTo(accountToSelect, false, false);
+
+ return oldAccountNames != null
+ && !(oldAccountNames.size() == mAccountNames.size()
+ && oldAccountNames.containsAll(mAccountNames));
}
/**
@@ -444,45 +433,146 @@ public class AccountFirstRunView extends FrameLayout
if (!mSignedIn) return;
String name = null;
- if (mIsChildAccount) name = mProfileData.getGivenName(mAccountName);
- if (name == null) name = mProfileData.getFullName(mAccountName);
+ if (mProfileData != null) {
+ if (mIsChildAccount) name = mProfileData.getGivenName(mAccountName);
+ if (name == null) name = mProfileData.getFullName(mAccountName);
+ }
if (name == null) name = mAccountName;
String text = String.format(getResources().getString(R.string.fre_hi_name), name);
- ((TextView) findViewById(R.id.title)).setText(text);
+ mTitle.setText(text);
}
/**
* Updates the view to show that sign in has completed.
*/
public void switchToSignedMode() {
+ showConfirmSignInPage();
+ }
+
+ private void showSignInPage() {
+ mSignedIn = false;
+ mTitle.setText(R.string.sign_in_to_chrome);
+
+ mSpinner.setEnabled(true);
+ mSpinner.setBackground(mSpinnerBackground);
+ mImageCarousel.setVisibility(VISIBLE);
+
+ setUpCancelButton();
+ updateAccounts();
+
+ mImageCarousel.setSignedInMode(false);
+ }
+
+ private void showConfirmSignInPage() {
mSignedIn = true;
updateProfileName();
mSpinner.setEnabled(false);
mSpinner.setBackground(null);
- mPositiveButton.setText(getResources().getText(R.string.fre_done));
- mPositiveButton.setOnClickListener(new OnClickListener() {
+ setUpConfirmButton();
+ setUpUndoButton();
+
+ if (mShowSettingsSpan) {
+ ClickableSpan settingsSpan = new ClickableSpan() {
+ @Override
+ public void onClick(View widget) {
+ mListener.onAccountSelected(mAccountName);
+ mListener.onSettingsClicked();
+ }
+
+ @Override
+ public void updateDrawState(TextPaint textPaint) {
+ textPaint.setColor(textPaint.linkColor);
+ textPaint.setUnderlineText(false);
+ }
+ };
+ mDescriptionText.setText(SpanApplier.applySpans(getSignedInDescription(mIsChildAccount),
+ new SpanInfo(SETTINGS_LINK_OPEN, SETTINGS_LINK_CLOSE, settingsSpan)));
+ } else {
+ // If we aren't showing the span, get rid of the LINK1 annotations.
+ mDescriptionText.setText(getSignedInDescription(mIsChildAccount)
+ .replace(SETTINGS_LINK_OPEN, "")
+ .replace(SETTINGS_LINK_CLOSE, ""));
+ }
+
+ mImageCarousel.setVisibility(VISIBLE);
+ mImageCarousel.setSignedInMode(true);
+ }
+
+ private void setUpCancelButton() {
+ setNegativeButtonVisible(true);
+
+ mNegativeButton.setText(getResources().getText(mCancelButtonTextId));
+ mNegativeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mListener.onSigningInCompleted(mAccountName);
+ setButtonsEnabled(false);
+ mListener.onAccountSelectionCanceled();
}
});
- mNegativeButton.setText(getResources().getText(R.string.fre_settings));
+ }
+
+ private void setUpSignInButton(boolean hasAccounts) {
+ if (hasAccounts) {
+ mPositiveButton.setText(R.string.choose_account_sign_in);
+ mPositiveButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showConfirmSignInPage();
+ }
+ });
+ } else {
+ mPositiveButton.setText(R.string.fre_no_accounts);
+ mPositiveButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mListener.onNewAccount();
+ }
+ });
+ }
+ }
+
+ private void setUpUndoButton() {
+ setNegativeButtonVisible(!isInForcedAccountMode());
+ if (isInForcedAccountMode()) return;
+
+ mNegativeButton.setText(getResources().getText(R.string.undo));
mNegativeButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- mListener.onSettingsButtonClicked(mAccountName);
+ showSignInPage();
+ }
+ });
+ }
+
+ private void setUpConfirmButton() {
+ mPositiveButton.setText(getResources().getText(R.string.fre_accept));
+ mPositiveButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mListener.onAccountSelected(mAccountName);
+ mListener.onDoneClicked();
}
});
- setButtonsEnabled(true);
- String text = getResources().getString(R.string.fre_signed_in_description);
- if (mIsChildAccount) {
- text += "\n" + getResources().getString(
- R.string.fre_signed_in_description_uca_addendum);
+ }
+
+ private void setNegativeButtonVisible(boolean enabled) {
+ if (enabled) {
+ mNegativeButton.setVisibility(View.VISIBLE);
+ findViewById(R.id.positive_button_end_padding).setVisibility(View.GONE);
+ } else {
+ mNegativeButton.setVisibility(View.GONE);
+ findViewById(R.id.positive_button_end_padding).setVisibility(View.INVISIBLE);
+ }
+ }
+
+ private String getSignedInDescription(boolean childAccount) {
+ if (childAccount) {
+ return getResources().getString(R.string.fre_signed_in_description) + '\n'
+ + getResources().getString(R.string.fre_signed_in_description_uca_addendum);
+ } else {
+ return getResources().getString(R.string.fre_signed_in_description);
}
- mDescriptionText.setText(text);
- mImageCarousel.setVisibility(VISIBLE);
- mImageCarousel.setSignedInMode();
}
/**

Powered by Google App Engine
This is Rietveld 408576698