Commit a1962dff authored by Tanmoy Mollik's avatar Tanmoy Mollik Committed by Commit Bot

[Android] Create Sync Promo Preference for the Main settings page

This preference will be used to show personalized sync promo in main
settings page

Screenshot: https://crbug.com/1106378#c2

Bug: 1106378
Change-Id: Iae286ef61f8b1d9166c9174a2fe964a12f6cf0f7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2310412
Commit-Queue: Tanmoy Mollik <triploblastic@chromium.org>
Reviewed-by: default avatarBoris Sazonov <bsazonov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#793674}
parent 6d21a259
...@@ -1485,6 +1485,7 @@ chrome_java_sources = [ ...@@ -1485,6 +1485,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java", "java/src/org/chromium/chrome/browser/sync/settings/SignInPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java", "java/src/org/chromium/chrome/browser/sync/settings/SyncAndServicesSettings.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java", "java/src/org/chromium/chrome/browser/sync/settings/SyncOffPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncPromoPreference.java",
"java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java", "java/src/org/chromium/chrome/browser/sync/settings/SyncSettingsUtils.java",
"java/src/org/chromium/chrome/browser/sync/ui/PassphraseActivity.java", "java/src/org/chromium/chrome/browser/sync/ui/PassphraseActivity.java",
"java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java", "java/src/org/chromium/chrome/browser/sync/ui/PassphraseCreationDialogFragment.java",
......
// Copyright 2020 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.sync.settings;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.PersonalizedSigninPromoView;
import org.chromium.chrome.browser.signin.ProfileDataCache;
import org.chromium.chrome.browser.signin.SigninPromoController;
import org.chromium.chrome.browser.signin.SigninPromoUtil;
import org.chromium.chrome.browser.sync.AndroidSyncSettings;
import org.chromium.chrome.browser.sync.ProfileSyncService;
import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener;
import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.AccountsChangeObserver;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.components.signin.metrics.SigninAccessPoint;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* A preference that displays Personalized Sync Promo when the user is not syncing.
*/
// TODO(https://crbug.com/1110889): Move all promos from SigninPreference to this class.
public class SyncPromoPreference extends Preference
implements ProfileDataCache.Observer, AndroidSyncSettings.AndroidSyncSettingsObserver,
SyncStateChangedListener, AccountsChangeObserver {
@Retention(RetentionPolicy.SOURCE)
@IntDef({State.PROMO_HIDDEN, State.PERSONALIZED_SYNC_PROMO})
public @interface State {
int PROMO_HIDDEN = 0;
int PERSONALIZED_SYNC_PROMO = 1;
}
private final ProfileDataCache mProfileDataCache;
private final AccountManagerFacade mAccountManagerFacade;
private @SignInPreference.State int mState;
private @Nullable SigninPromoController mSigninPromoController;
/**
* Constructor for inflating from XML.
*/
public SyncPromoPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mProfileDataCache =
ProfileDataCache.createProfileDataCache(context, R.drawable.ic_sync_badge_off_20dp);
mAccountManagerFacade = AccountManagerFacadeProvider.getInstance();
// State will be updated in registerForUpdates.
mState = State.PROMO_HIDDEN;
setVisible(false);
}
/**
* Starts listening for updates to the sign-in and sync state.
* TODO(https://crbug.com/1109713): Remove this method and use onAttached() instead
*/
public void registerForUpdates() {
mAccountManagerFacade.addObserver(this);
mProfileDataCache.addObserver(this);
FirstRunSignInProcessor.updateSigninManagerFirstRunCheckDone();
AndroidSyncSettings.get().registerObserver(this);
ProfileSyncService syncService = ProfileSyncService.get();
if (syncService != null) {
syncService.addSyncStateChangedListener(this);
}
update();
}
/**
* Stops listening for updates to the sign-in and sync state. Every call to registerForUpdates()
* must be matched with a call to this method.
* TODO(https://crbug.com/1109713): Remove this method and use onAttached() instead
*/
public void unregisterForUpdates() {
mAccountManagerFacade.removeObserver(this);
mProfileDataCache.removeObserver(this);
AndroidSyncSettings.get().unregisterObserver(this);
ProfileSyncService syncService = ProfileSyncService.get();
if (syncService != null) {
syncService.removeSyncStateChangedListener(this);
}
}
/**
* Should be called when the {@link PreferenceFragmentCompat} which used {@link
* SyncPromoPreference} gets destroyed. Used to record "ImpressionsTilDismiss" histogram.
*/
public void onPreferenceFragmentDestroyed() {
if (mSigninPromoController != null) {
mSigninPromoController.onPromoDestroyed();
}
}
/** Returns the state of the preference. Not valid until registerForUpdates is called. */
@State
public int getState() {
return mState;
}
/** Updates the title, summary, and image based on the current sign-in state. */
private void update() {
// If feature is not enabled keep the preference at the default PROMO_NONE state.
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.MOBILE_IDENTITY_CONSISTENCY)) {
return;
}
boolean personalizedPromoDismissed = SharedPreferencesManager.getInstance().readBoolean(
ChromePreferenceKeys.SIGNIN_PROMO_SETTINGS_PERSONALIZED_DISMISSED, false);
if (isSignedInButNotSyncing() && !personalizedPromoDismissed
&& SigninPromoController.hasNotReachedImpressionLimit(SigninAccessPoint.SETTINGS)) {
setupPersonalizedSyncPromo();
return;
}
if (mSigninPromoController != null) {
// Don't change the promo type if the new promo is already being shown.
setupPersonalizedSyncPromo();
return;
}
setupPromoHidden();
}
private void setupPersonalizedSyncPromo() {
mState = State.PERSONALIZED_SYNC_PROMO;
setLayoutResource(R.layout.personalized_signin_promo_view_settings);
setVisible(true);
if (mSigninPromoController == null) {
mSigninPromoController = new SigninPromoController(SigninAccessPoint.SETTINGS);
}
notifyChanged();
}
private void setupPromoHidden() {
mState = State.PROMO_HIDDEN;
mSigninPromoController = null;
setVisible(false);
}
private boolean isSignedInButNotSyncing() {
IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager(
Profile.getLastUsedRegularProfile());
return !identityManager.hasPrimaryAccount()
&& identityManager.getPrimaryAccountInfo(ConsentLevel.NOT_REQUIRED) != null;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
if (mSigninPromoController == null) {
return;
}
PersonalizedSigninPromoView syncPromoView =
(PersonalizedSigninPromoView) holder.findViewById(R.id.signin_promo_view_container);
// TODO(https://crbug.com/1095628): Use setupPersonalizedSyncPromo here.
SigninPromoUtil.setupPromoViewFromCache(
mSigninPromoController, mProfileDataCache, syncPromoView, () -> {
SharedPreferencesManager.getInstance().writeBoolean(
ChromePreferenceKeys.SIGNIN_PROMO_SETTINGS_PERSONALIZED_DISMISSED,
true);
setupPromoHidden();
});
syncPromoView.getStatusMessage().setVisibility(View.VISIBLE);
syncPromoView.getChooseAccountButton().setVisibility(View.GONE);
syncPromoView.getSigninButton().setText(R.string.sync_promo_turn_on_sync);
}
// ProfileSyncServiceListener implementation.
@Override
public void syncStateChanged() {
update();
}
// ProfileDataCache.Observer implementation.
@Override
public void onProfileDataUpdated(String accountId) {
update();
}
// AndroidSyncSettings.AndroidSyncSettingsObserver implementation.
@Override
public void androidSyncSettingsChanged() {
update();
}
// AccountsChangeObserver implementation.
@Override
public void onAccountsChanged() {
update();
}
}
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