| Index: chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5579001c1a3b5bdd09932b936014021b10088659
|
| --- /dev/null
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java
|
| @@ -0,0 +1,265 @@
|
| +// Copyright 2016 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.content.Context;
|
| +import android.content.Intent;
|
| +import android.provider.Settings;
|
| +import android.view.LayoutInflater;
|
| +import android.view.View;
|
| +import android.widget.Button;
|
| +import android.widget.FrameLayout;
|
| +import android.widget.TextView;
|
| +
|
| +import org.chromium.chrome.R;
|
| +import org.chromium.chrome.browser.preferences.PreferencesLauncher;
|
| +import org.chromium.chrome.browser.signin.AccountSigninActivity.AccessPoint;
|
| +import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver;
|
| +import org.chromium.chrome.browser.sync.ui.SyncCustomizationFragment;
|
| +import org.chromium.sync.AndroidSyncSettings;
|
| +import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver;
|
| +import org.chromium.sync.signin.ChromeSigninController;
|
| +
|
| +/**
|
| + * A View that shows the user the next step they must complete to start syncing their data (eg.
|
| + * Recent Tabs or Bookmarks). For example, if the user is not signed in, the View will prompt them
|
| + * to do so and link to the AccountSigninActivity.
|
| + */
|
| +public class SigninAndSyncView extends FrameLayout
|
| + implements AndroidSyncSettingsObserver, SignInStateObserver {
|
| + private static final String TAG = "SigninAndSyncView";
|
| + private final Listener mListener;
|
| + private final int mAccessPoint;
|
| + @AccessPoint private final SigninManager mSigninManager;
|
| +
|
| + private final TextView mTitle;
|
| + private final TextView mDescription;
|
| + private final Button mNegativeButton;
|
| + private final Button mPositiveButton;
|
| +
|
| + /**
|
| + * A listener for the container of the SigninAndSyncView to be informed of certain user
|
| + * interactions.
|
| + */
|
| + public interface Listener {
|
| + /**
|
| + * The user has pressed 'no thanks' and expects the view to be removed from its parent.
|
| + */
|
| + public void onViewDismissed();
|
| + }
|
| +
|
| + /**
|
| + * Constructor for use from Java.
|
| + */
|
| + public SigninAndSyncView(Context context, Listener listener, @AccessPoint int accessPoint) {
|
| + // TODO(peconn): Simplify BookmarkPromoHeader
|
| + super(context);
|
| + mListener = listener;
|
| + mAccessPoint = accessPoint;
|
| +
|
| + assert mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER
|
| + || mAccessPoint == SigninAccessPoint.RECENT_TABS
|
| + : "SigninAndSyncView only has strings for bookmark manager and recent tabs.";
|
| +
|
| + mSigninManager = SigninManager.get(getContext());
|
| +
|
| + addView(LayoutInflater.from(getContext())
|
| + .inflate(R.layout.signin_and_sync_view, this, false));
|
| +
|
| + mTitle = (TextView) findViewById(R.id.title);
|
| + mDescription = (TextView) findViewById(R.id.description);
|
| + mNegativeButton = (Button) findViewById(R.id.no_thanks);
|
| + mPositiveButton = (Button) findViewById(R.id.sign_in);
|
| +
|
| + // The title stays the same no matter what action the user must take.
|
| + if (mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER) {
|
| + mTitle.setText(R.string.sync_your_bookmarks);
|
| + } else {
|
| + mTitle.setVisibility(View.GONE);
|
| + }
|
| +
|
| + // We don't need to call update() here as it will be called in onAttachedToWindow().
|
| + }
|
| +
|
| + private void update() {
|
| + ViewState viewState;
|
| + if (!ChromeSigninController.get(getContext()).isSignedIn()) {
|
| + viewState = getStateForSignin();
|
| + } else if (!AndroidSyncSettings.isMasterSyncEnabled(getContext())) {
|
| + viewState = getStateForEnableAndroidSync();
|
| + } else if (!AndroidSyncSettings.isChromeSyncEnabled(getContext())) {
|
| + viewState = getStateForEnableChromeSync();
|
| + } else {
|
| + viewState = getStateForStartUsing();
|
| + }
|
| + viewState.apply(mDescription, mPositiveButton, mNegativeButton);
|
| + }
|
| +
|
| + /**
|
| + * The ViewState class represents all the UI elements that can change for each variation of
|
| + * this View. We use this to ensure each variation (created in the getStateFor* methods)
|
| + * explicitly touches each UI element.
|
| + */
|
| + private static class ViewState {
|
| + private final int mDescriptionText;
|
| + private final ButtonState mPositiveButtonState;
|
| + private final ButtonState mNegativeButtonState;
|
| +
|
| + public ViewState(int mDescriptionText,
|
| + ButtonState mPositiveButtonState, ButtonState mNegativeButtonState) {
|
| + this.mDescriptionText = mDescriptionText;
|
| + this.mPositiveButtonState = mPositiveButtonState;
|
| + this.mNegativeButtonState = mNegativeButtonState;
|
| + }
|
| +
|
| + public void apply(TextView description, Button positiveButton, Button negativeButton) {
|
| + description.setText(mDescriptionText);
|
| + mNegativeButtonState.apply(negativeButton);
|
| + mPositiveButtonState.apply(positiveButton);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Classes to represent the state of a button that we are interested in, used to keep ViewState
|
| + * tidy and provide some convenience methods.
|
| + */
|
| + private interface ButtonState {
|
| + public void apply(Button button);
|
| + }
|
| +
|
| + private static class ButtonAbsent implements ButtonState {
|
| + @Override
|
| + public void apply(Button button) {
|
| + button.setVisibility(View.GONE);
|
| + }
|
| + }
|
| +
|
| + private static class ButtonPresent implements ButtonState {
|
| + private final int mTextResource;
|
| + private final OnClickListener mOnClickListener;
|
| +
|
| + public ButtonPresent(int textResource, OnClickListener onClickListener) {
|
| + mTextResource = textResource;
|
| + mOnClickListener = onClickListener;
|
| + }
|
| +
|
| + @Override
|
| + public void apply(Button button) {
|
| + button.setVisibility(View.VISIBLE);
|
| + button.setText(mTextResource);
|
| + button.setOnClickListener(mOnClickListener);
|
| + }
|
| + }
|
| +
|
| + private ViewState getStateForSignin() {
|
| + int descId = mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER
|
| + ? R.string.bookmark_sign_in_promo_description
|
| + : R.string.recent_tabs_sign_in_promo_description;
|
| +
|
| + ButtonState positiveButton = new ButtonPresent(
|
| + R.string.sign_in_button,
|
| + new OnClickListener() {
|
| + @Override
|
| + public void onClick(View view) {
|
| + AccountSigninActivity
|
| + .startAccountSigninActivity(getContext(), mAccessPoint);
|
| + }
|
| + });
|
| +
|
| + ButtonState negativeButton;
|
| + if (mAccessPoint == SigninAccessPoint.RECENT_TABS) {
|
| + negativeButton = new ButtonAbsent();
|
| + } else {
|
| + negativeButton = new ButtonPresent(R.string.no_thanks, new OnClickListener() {
|
| + @Override
|
| + public void onClick(View view) {
|
| + mListener.onViewDismissed();
|
| + }
|
| + });
|
| + }
|
| +
|
| + return new ViewState(descId, positiveButton, negativeButton);
|
| + }
|
| +
|
| + private ViewState getStateForEnableAndroidSync() {
|
| + assert mAccessPoint == SigninAccessPoint.RECENT_TABS
|
| + : "Enable Android Sync should not be showing from bookmarks";
|
| +
|
| + int descId = R.string.recent_tabs_sync_promo_enable_android_sync;
|
| +
|
| + ButtonState positiveButton = new ButtonPresent(
|
| + R.string.open_settings_button,
|
| + new OnClickListener() {
|
| + @Override
|
| + public void onClick(View v) {
|
| + // TODO(crbug.com/557784): Like AccountManagementFragment, this would also
|
| + // benefit from going directly to an account.
|
| + Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
|
| + intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {"com.google"});
|
| + getContext().startActivity(intent);
|
| + }
|
| + });
|
| +
|
| + return new ViewState(descId, positiveButton, new ButtonAbsent());
|
| + }
|
| +
|
| + private ViewState getStateForEnableChromeSync() {
|
| + int descId = mAccessPoint == SigninAccessPoint.BOOKMARK_MANAGER
|
| + ? R.string.bookmarks_sync_promo_enable_sync
|
| + : R.string.recent_tabs_sync_promo_enable_chrome_sync;
|
| +
|
| + ButtonState positiveButton = new ButtonPresent(
|
| + R.string.enable_sync_button,
|
| + new OnClickListener() {
|
| + @Override
|
| + public void onClick(View v) {
|
| + PreferencesLauncher.launchSettingsPage(getContext(),
|
| + SyncCustomizationFragment.class.getName());
|
| + }
|
| + });
|
| +
|
| + return new ViewState(descId, positiveButton, new ButtonAbsent());
|
| + }
|
| +
|
| + private ViewState getStateForStartUsing() {
|
| + assert mAccessPoint == SigninAccessPoint.RECENT_TABS
|
| + : "This should not be showing from bookmarks";
|
| +
|
| + return new ViewState(R.string.ntp_recent_tabs_sync_promo_instructions,
|
| + new ButtonAbsent(), new ButtonAbsent());
|
| + }
|
| +
|
| + @Override
|
| + protected void onAttachedToWindow() {
|
| + super.onAttachedToWindow();
|
| + mSigninManager.addSignInStateObserver(this);
|
| + AndroidSyncSettings.registerObserver(getContext(), this);
|
| + update();
|
| + }
|
| +
|
| + @Override
|
| + protected void onDetachedFromWindow() {
|
| + super.onDetachedFromWindow();
|
| + mSigninManager.removeSignInStateObserver(this);
|
| + AndroidSyncSettings.unregisterObserver(getContext(), this);
|
| + }
|
| +
|
| + // SigninStateObserver
|
| + @Override
|
| + public void onSignedIn() {
|
| + update();
|
| + }
|
| +
|
| + @Override
|
| + public void onSignedOut() {
|
| + update();
|
| + }
|
| +
|
| + // AndroidSyncStateObserver
|
| + @Override
|
| + public void androidSyncSettingsChanged() {
|
| + update();
|
| + }
|
| +}
|
|
|