blob: 9decf4f3d615f0eb2f0681df2daa6249441823d5 [file] [log] [blame]
// 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.accounts.Account;
import android.app.Activity;
import android.text.TextUtils;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import androidx.collection.ArraySet;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.services.DisplayableProfileData;
import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.services.SigninPreferencesManager;
import org.chromium.chrome.browser.version.ChromeVersionInfo;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.AccountUtils;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import org.chromium.components.signin.metrics.SigninAccessPoint;
import org.chromium.components.user_prefs.UserPrefs;
import org.chromium.ui.base.WindowAndroid;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Helper functions for promoting sign in.
*/
public class SigninPromoUtil {
private SigninPromoUtil() {}
/**
* Launches the signin promo if it needs to be displayed.
* @param activity The parent activity.
* @return Whether the signin promo is shown.
*/
public static boolean launchSigninPromoIfNeeded(final Activity activity) {
if (!AccountManagerFacadeProvider.getInstance().isCachePopulated()) {
// Suppress the promo if the account list isn't available yet.
return false;
}
SigninPreferencesManager preferencesManager = SigninPreferencesManager.getInstance();
int currentMajorVersion = ChromeVersionInfo.getProductMajorVersion();
boolean isSignedIn = IdentityServicesProvider.get()
.getIdentityManager(Profile.getLastUsedRegularProfile())
.hasPrimaryAccount();
boolean wasSignedIn =
TextUtils.isEmpty(UserPrefs.get(Profile.getLastUsedRegularProfile())
.getString(Pref.GOOGLE_SERVICES_LAST_USERNAME));
Set<String> accountNames = new ArraySet<>(AccountUtils.toAccountNames(
AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts()));
if (!shouldLaunchSigninPromo(preferencesManager, currentMajorVersion, isSignedIn,
wasSignedIn, accountNames)) {
return false;
}
SigninUtils.startSigninActivityIfAllowed(activity, SigninAccessPoint.SIGNIN_PROMO);
preferencesManager.setSigninPromoLastShownVersion(currentMajorVersion);
preferencesManager.setSigninPromoLastAccountNames(accountNames);
return true;
}
/**
* Launches the signin promo if it needs to be displayed.
* @param preferencesManager the preferences manager to persist data
* @param currentMajorVersion the current major version of Chrome
* @param isSignedIn is user currently signed in
* @param wasSignedIn has used manually signed out
* @param accountNames the list of accounts on the device
* @return Whether the signin promo should be shown.
*/
@VisibleForTesting
static boolean shouldLaunchSigninPromo(SigninPreferencesManager preferencesManager,
int currentMajorVersion, boolean isSignedIn, boolean wasSignedIn,
Set<String> accountNames) {
int lastPromoMajorVersion = preferencesManager.getSigninPromoLastShownVersion();
if (lastPromoMajorVersion == 0) {
preferencesManager.setSigninPromoLastShownVersion(currentMajorVersion);
return false;
}
// Don't show if user is signed in.
if (isSignedIn) return false;
// Don't show if user has manually signed out.
if (wasSignedIn) return false;
// Promo can be shown at most once every 2 Chrome major versions.
if (currentMajorVersion < lastPromoMajorVersion + 2) return false;
// Don't show if the account list isn't available yet or there are no accounts in it.
if (accountNames.isEmpty()) return false;
// Don't show if no new accounts have been added after the last time promo was shown.
Set<String> previousAccountNames = preferencesManager.getSigninPromoLastAccountNames();
return previousAccountNames == null || !previousAccountNames.containsAll(accountNames);
}
/**
* @param signinPromoController The {@link SigninPromoController} that maintains the view.
* @param profileDataCache The {@link ProfileDataCache} that stores profile data.
* @param view The {@link PersonalizedSigninPromoView} that should be set up.
* @param listener The {@link SigninPromoController.OnDismissListener} to be set to the view.
*/
public static void setupSigninPromoViewFromCache(SigninPromoController signinPromoController,
ProfileDataCache profileDataCache, PersonalizedSigninPromoView view,
SigninPromoController.OnDismissListener listener) {
DisplayableProfileData profileData = null;
List<Account> accounts = AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts();
if (accounts.size() > 0) {
String defaultAccountName = accounts.get(0).name;
profileDataCache.update(Collections.singletonList(defaultAccountName));
profileData = profileDataCache.getProfileDataOrDefault(defaultAccountName);
}
signinPromoController.detach();
signinPromoController.setupPromoView(view.getContext(), view, profileData, listener);
}
/**
* @param signinPromoController The {@link SigninPromoController} that maintains the view.
* @param profileDataCache The {@link ProfileDataCache} that stores profile data.
* @param view The {@link PersonalizedSigninPromoView} that should be set up.
* @param listener The {@link SigninPromoController.OnDismissListener} to be set to the view.
*/
public static void setupSyncPromoViewFromCache(SigninPromoController signinPromoController,
ProfileDataCache profileDataCache, PersonalizedSigninPromoView view,
SigninPromoController.OnDismissListener listener) {
String signedInAccount = CoreAccountInfo.getEmailFrom(
IdentityServicesProvider.get()
.getIdentityManager(Profile.getLastUsedRegularProfile())
.getPrimaryAccountInfo(ConsentLevel.NOT_REQUIRED));
assert signedInAccount != null : "Sync promo should only be shown for a signed in account";
profileDataCache.update(Collections.singletonList(signedInAccount));
DisplayableProfileData profileData =
profileDataCache.getProfileDataOrDefault(signedInAccount);
signinPromoController.detach();
signinPromoController.setupPromoView(view.getContext(), view, profileData, listener);
view.getPrimaryButton().setText(R.string.sync_promo_turn_on_sync);
view.getSecondaryButton().setVisibility(View.GONE);
}
/**
* A convenience method to create an SigninActivity, passing the access point as an
* intent extra.
* @param window WindowAndroid from which to get the Activity/Context.
* @param accessPoint for metrics purposes.
*/
@CalledByNative
private static void openSigninActivityForPromo(WindowAndroid window, int accessPoint) {
Activity activity = window.getActivity().get();
if (activity != null) {
SigninUtils.startSigninActivityIfAllowed(activity, accessPoint);
}
}
}