org.chromium.sync.signin.ChromeSigninController Java Examples

The following examples show how to use org.chromium.sync.signin.ChromeSigninController. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SigninPromoUtil.java    From delion with Apache License 2.0 6 votes vote down vote up
/**
 * 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) {
    // The promo is displayed if Chrome is launched directly (i.e., not with the intent to
    // navigate to and view a URL on startup), the instance is part of the field trial,
    // and the promo has been marked to display.
    ChromePreferenceManager preferenceManager = ChromePreferenceManager.getInstance(activity);
    if (MultiWindowUtils.getInstance().isLegacyMultiWindow(activity)) return false;
    if (!preferenceManager.getShowSigninPromo()) return false;
    preferenceManager.setShowSigninPromo(false);

    String lastSyncName = PrefServiceBridge.getInstance().getSyncLastAccountName();
    if (ChromeSigninController.get(activity).isSignedIn() || !TextUtils.isEmpty(lastSyncName)) {
        return false;
    }

    AccountSigninActivity.startAccountSigninActivity(activity, SigninAccessPoint.SIGNIN_PROMO);
    preferenceManager.setSigninPromoShown();
    return true;
}
 
Example #2
Source File: AccountsChangedReceiver.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void onReceive(final Context context, Intent intent) {
    if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
        final Account signedInUser =
                ChromeSigninController.get(context).getSignedInUser();
        if (signedInUser != null) {
            BrowserStartupController.StartupCallback callback =
                    new BrowserStartupController.StartupCallback() {
                @Override
                public void onSuccess(boolean alreadyStarted) {
                    OAuth2TokenService.getForProfile(Profile.getLastUsedProfile())
                            .validateAccounts(context);
                }

                @Override
                public void onFailure() {
                    Log.w(TAG, "Failed to start browser process.");
                }
            };
            startBrowserProcessOnUiThread(context, callback);
        }
    }
}
 
Example #3
Source File: SigninManager.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Signs out of Chrome.
 * <p/>
 * This method clears the signed-in username, stops sync and sends out a
 * sign-out notification on the native side.
 *
 * @param activity If not null then a progress dialog is shown over the activity until signout
 * completes, in case the account had management enabled. The activity must be valid until the
 * callback is invoked.
 * @param callback Will be invoked after signout completes, if not null.
 */
public void signOut(Activity activity, Runnable callback) {
    mSignOutCallback = callback;

    boolean wipeData = getManagementDomain() != null;
    Log.d(TAG, "Signing out, wipe data? " + wipeData);

    ChromeSigninController.get(mContext).clearSignedInUser();
    ProfileSyncService.get(mContext).signOut();
    nativeSignOut(mNativeSigninManagerAndroid);

    if (wipeData) {
        wipeProfileData(activity);
    } else {
        onSignOutDone();
    }
}
 
Example #4
Source File: PassphraseActivity.java    From delion with Apache License 2.0 6 votes vote down vote up
@Override
protected void onResume() {
    super.onResume();
    Account account = ChromeSigninController.get(this).getSignedInUser();
    if (account == null) {
        finish();
        return;
    }

    if (!isShowingDialog(FRAGMENT_PASSPHRASE)) {
        if (ProfileSyncService.get().isBackendInitialized()) {
            displayPassphraseDialog();
        } else {
            addSyncStateChangedListener();
            displaySpinnerDialog();
        }
    }
}
 
Example #5
Source File: InvalidationService.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void requestAuthToken(final PendingIntent pendingIntent,
        @Nullable String invalidAuthToken) {
    @Nullable Account account = ChromeSigninController.get(this).getSignedInUser();
    if (account == null) {
        // This should never happen, because this code should only be run if a user is
        // signed-in.
        Log.w(TAG, "No signed-in user; cannot send message to data center");
        return;
    }

    // Attempt to retrieve a token for the user. This method will also invalidate
    // invalidAuthToken if it is non-null.
    AccountManagerHelper.get(this).getNewAuthTokenFromForeground(
            account, invalidAuthToken, getOAuth2ScopeWithType(),
            new AccountManagerHelper.GetAuthTokenCallback() {
                @Override
                public void tokenAvailable(String token) {
                    if (token != null) {
                        setAuthToken(InvalidationService.this.getApplicationContext(),
                                pendingIntent, token, getOAuth2ScopeWithType());
                    }
                }
            });
}
 
Example #6
Source File: InvalidationService.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Requests that the sync system perform a sync.
 *
 * @param objectId the object that changed, if known.
 * @param version the version of the object that changed, if known.
 * @param payload the payload of the change, if known.
 */
private void requestSync(@Nullable ObjectId objectId, @Nullable Long version,
        @Nullable String payload) {
    // Construct the bundle to supply to the native sync code.
    Bundle bundle = new Bundle();
    if (objectId == null && version == null && payload == null) {
        // Use an empty bundle in this case for compatibility with the v1 implementation.
    } else {
        if (objectId != null) {
            bundle.putInt("objectSource", objectId.getSource());
            bundle.putString("objectId", new String(objectId.getName()));
        }
        // We use "0" as the version if we have an unknown-version invalidation. This is OK
        // because the native sync code special-cases zero and always syncs for invalidations at
        // that version (Tango defines a special UNKNOWN_VERSION constant with this value).
        bundle.putLong("version", (version == null) ? 0 : version);
        bundle.putString("payload", (payload == null) ? "" : payload);
    }
    Account account = ChromeSigninController.get(this).getSignedInUser();
    String contractAuthority = SyncStatusHelper.get(this).getContractAuthority();
    requestSyncFromContentResolver(bundle, account, contractAuthority);
}
 
Example #7
Source File: AccountsChangedReceiver.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void onReceive(final Context context, Intent intent) {
    if (AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION.equals(intent.getAction())) {
        final Account signedInUser =
                ChromeSigninController.get(context).getSignedInUser();
        if (signedInUser != null) {
            BrowserStartupController.StartupCallback callback =
                    new BrowserStartupController.StartupCallback() {
                @Override
                public void onSuccess(boolean alreadyStarted) {
                    OAuth2TokenService.getForProfile(Profile.getLastUsedProfile())
                            .validateAccounts(context);
                }

                @Override
                public void onFailure() {
                    Log.w(TAG, "Failed to start browser process.");
                }
            };
            startBrowserProcessOnUiThread(context, callback);
        }
    }
}
 
Example #8
Source File: SigninManager.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Signs out of Chrome.
 * <p/>
 * This method clears the signed-in username, stops sync and sends out a
 * sign-out notification on the native side.
 *
 * @param activity If not null then a progress dialog is shown over the activity until signout
 * completes, in case the account had management enabled. The activity must be valid until the
 * callback is invoked.
 * @param callback Will be invoked after signout completes, if not null.
 */
public void signOut(Activity activity, Runnable callback) {
    mSignOutCallback = callback;

    boolean wipeData = getManagementDomain() != null;
    Log.d(TAG, "Signing out, wipe data? " + wipeData);

    ChromeSigninController.get(mContext).clearSignedInUser();
    ProfileSyncService.get(mContext).signOut();
    nativeSignOut(mNativeSigninManagerAndroid);

    if (wipeData) {
        wipeProfileData(activity);
    } else {
        onSignOutDone();
    }
}
 
Example #9
Source File: AccountManagementFragment.java    From delion with Apache License 2.0 6 votes vote down vote up
/**
 * Prefetch the primary account image and name.
 *
 * @param context A context to use.
 * @param profile A profile to use.
 */
public static void prefetchUserNamePicture(Context context, Profile profile) {
    final String accountName = ChromeSigninController.get(context).getSignedInAccountName();
    if (TextUtils.isEmpty(accountName)) return;
    if (sToNamePicture.get(accountName) != null) return;

    ProfileDownloader.addObserver(new ProfileDownloader.Observer() {
        @Override
        public void onProfileDownloaded(String accountId, String fullName, String givenName,
                Bitmap bitmap) {
            if (TextUtils.equals(accountName, accountId)) {
                updateUserNamePictureCache(accountId, fullName, bitmap);
                ProfileDownloader.removeObserver(this);
            }
        }
    });
    startFetchingAccountInformation(context, profile, accountName);
}
 
Example #10
Source File: AccountManagementFragment.java    From delion with Apache License 2.0 6 votes vote down vote up
@Override
public void onSignOutClicked() {
    // In case the user reached this fragment without being signed in, we guard the sign out so
    // we do not hit a native crash.
    if (!ChromeSigninController.get(getActivity()).isSignedIn()) return;

    final Activity activity = getActivity();
    final DialogFragment clearDataProgressDialog = new ClearDataProgressDialog();
    SigninManager.get(activity).signOut(null, new SigninManager.WipeDataHooks() {
        @Override
        public void preWipeData() {
            clearDataProgressDialog.show(
                    activity.getFragmentManager(), CLEAR_DATA_PROGRESS_DIALOG_TAG);
        }
        @Override
        public void postWipeData() {
            if (clearDataProgressDialog.isAdded()) {
                clearDataProgressDialog.dismissAllowingStateLoss();
            }
        }
    });
    AccountManagementScreenHelper.logEvent(
            ProfileAccountManagementMetrics.SIGNOUT_SIGNOUT,
            mGaiaServiceType);
}
 
Example #11
Source File: OAuth2TokenService.java    From delion with Apache License 2.0 6 votes vote down vote up
private void validateAccountsWithSignedInAccountName(
        Context context, boolean forceNotifications) {
    String currentlySignedInAccount =
            ChromeSigninController.get(context).getSignedInAccountName();
    if (currentlySignedInAccount != null
            && isSignedInAccountChanged(context, currentlySignedInAccount)) {
        // Set currentlySignedInAccount to null for validation if signed-in account was changed
        // (renamed or removed from the device), this will cause all credentials in token
        // service be revoked.
        // Could only get here during Chrome cold startup.
        // After chrome started, SigninHelper and AccountsChangedReceiver will handle account
        // change (re-signin or sign out signed-in account).
        currentlySignedInAccount = null;
    }
    nativeValidateAccounts(mNativeOAuth2TokenServiceDelegateAndroid, currentlySignedInAccount,
            forceNotifications);
}
 
Example #12
Source File: InvalidationService.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
/**
 * Requests that the sync system perform a sync.
 *
 * @param objectId the object that changed, if known.
 * @param version the version of the object that changed, if known.
 * @param payload the payload of the change, if known.
 */
private void requestSync(@Nullable ObjectId objectId, @Nullable Long version,
        @Nullable String payload) {
    // Construct the bundle to supply to the native sync code.
    Bundle bundle = new Bundle();
    if (objectId == null && version == null && payload == null) {
        // Use an empty bundle in this case for compatibility with the v1 implementation.
    } else {
        if (objectId != null) {
            bundle.putInt("objectSource", objectId.getSource());
            bundle.putString("objectId", new String(objectId.getName()));
        }
        // We use "0" as the version if we have an unknown-version invalidation. This is OK
        // because the native sync code special-cases zero and always syncs for invalidations at
        // that version (Tango defines a special UNKNOWN_VERSION constant with this value).
        bundle.putLong("version", (version == null) ? 0 : version);
        bundle.putString("payload", (payload == null) ? "" : payload);
    }
    Account account = ChromeSigninController.get(this).getSignedInUser();
    String contractAuthority = SyncStatusHelper.get(this).getContractAuthority();
    requestSyncFromContentResolver(bundle, account, contractAuthority);
}
 
Example #13
Source File: InvalidationService.java    From android-chromium with BSD 2-Clause "Simplified" License 6 votes vote down vote up
@Override
public void requestAuthToken(final PendingIntent pendingIntent,
        @Nullable String invalidAuthToken) {
    @Nullable Account account = ChromeSigninController.get(this).getSignedInUser();
    if (account == null) {
        // This should never happen, because this code should only be run if a user is
        // signed-in.
        Log.w(TAG, "No signed-in user; cannot send message to data center");
        return;
    }

    // Attempt to retrieve a token for the user. This method will also invalidate
    // invalidAuthToken if it is non-null.
    AccountManagerHelper.get(this).getNewAuthTokenFromForeground(
            account, invalidAuthToken, getOAuth2ScopeWithType(),
            new AccountManagerHelper.GetAuthTokenCallback() {
                @Override
                public void tokenAvailable(String token) {
                    if (token != null) {
                        setAuthToken(InvalidationService.this.getApplicationContext(),
                                pendingIntent, token, getOAuth2ScopeWithType());
                    }
                }
            });
}
 
Example #14
Source File: SigninManager.java    From delion with Apache License 2.0 6 votes vote down vote up
/**
 * Signs out of Chrome.
 * <p/>
 * This method clears the signed-in username, stops sync and sends out a
 * sign-out notification on the native side.
 *
 * @param callback Will be invoked after signout completes, if not null.
 * @param wipeDataHooks Hooks to call during data wiping in case the account is managed.
 */
public void signOut(Runnable callback, WipeDataHooks wipeDataHooks) {
    mSignOutInProgress = true;
    mSignOutCallback = callback;

    boolean wipeData = getManagementDomain() != null;
    Log.d(TAG, "Signing out, wipe data? " + wipeData);

    // Native signout must happen before resetting the account so data is deleted correctly.
    // http://crbug.com/589028
    nativeSignOut(mNativeSigninManagerAndroid);
    ChromeSigninController.get(mContext).setSignedInAccountName(null);

    if (wipeData) {
        wipeProfileData(wipeDataHooks);
    } else {
        onSignOutDone();
    }

    AccountTrackerService.get(mContext).invalidateAccountSeedStatus(true);
}
 
Example #15
Source File: AccountManagementFragment.java    From delion with Apache License 2.0 6 votes vote down vote up
private void configureSyncSettings() {
    final Preferences preferences = (Preferences) getActivity();
    final Account account = ChromeSigninController.get(getActivity()).getSignedInUser();
    findPreference(PREF_SYNC_SETTINGS)
            .setOnPreferenceClickListener(new OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {
                    if (!isVisible() || !isResumed()) return false;

                    if (ProfileSyncService.get() == null) return true;

                    if (AndroidSyncSettings.isMasterSyncEnabled(preferences)) {
                        Bundle args = new Bundle();
                        args.putString(
                                SyncCustomizationFragment.ARGUMENT_ACCOUNT, account.name);
                        preferences.startFragment(
                                SyncCustomizationFragment.class.getName(), args);
                    } else {
                        openSyncSettingsPage(preferences);
                    }

                    return true;
                }
            });
}
 
Example #16
Source File: ChromiumTestShellActivity.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.signin:
            if (ChromeSigninController.get(this).isSignedIn())
                SyncController.openSignOutDialog(getFragmentManager());
            else
                SyncController.openSigninDialog(getFragmentManager());
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
 
Example #17
Source File: AutoLoginAccountDelegate.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public boolean logIn() {
    Log.i("AutoLoginAccountDelegate", "auto-login requested for "
            + (mAccount != null ? mAccount.toString() : "?"));

    Account currentAccount = ChromeSigninController.get(mActivity).getSignedInUser();
    if (mAccount == null || !mAccount.equals(currentAccount)) {
        Log.i("InfoBar", "auto-login failed because account is no longer valid");
        return false;
    }

    // The callback for this request comes in on a non-UI thread.
    mAccountManager.getAuthToken(mAccount, mAuthTokenType, null, mActivity, this, null);
    mLogInRequested = true;
    return true;
}
 
Example #18
Source File: ChromiumTestShellActivity.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menu.setGroupVisible(R.id.MAIN_MENU, true);
    MenuItem signinItem = menu.findItem(R.id.signin);
    if (ChromeSigninController.get(this).isSignedIn())
        signinItem.setTitle(ChromeSigninController.get(this).getSignedInAccountName());
    else
        signinItem.setTitle(R.string.signin_sign_in);
    return true;
}
 
Example #19
Source File: ChromiumTestShellActivity.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.signin:
            if (ChromeSigninController.get(this).isSignedIn())
                SyncController.openSignOutDialog(getFragmentManager());
            else
                SyncController.openSigninDialog(getFragmentManager());
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}
 
Example #20
Source File: SyncStatusHelper.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public void onStatusChanged(int which) {
    if (ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS == which) {
        // Sync settings have changed; update our in-memory caches
        updateMasterSyncAutomaticallySetting();
        synchronized (mCachedSettings) {
            mCachedSettings.updateSyncSettingsForAccount(
                    ChromeSigninController.get(mApplicationContext).getSignedInUser());
        }
        notifyObservers();
    }
}
 
Example #21
Source File: OAuth2TokenService.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void validateAccounts(Context context) {
    ThreadUtils.assertOnUiThread();
    String currentlySignedInAccount =
            ChromeSigninController.get(context).getSignedInAccountName();
    String[] accounts = getAccounts(context);
    nativeValidateAccounts(
            mNativeProfileOAuth2TokenService, accounts, currentlySignedInAccount);
}
 
Example #22
Source File: SyncStatusHelper.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
@Override
public void onStatusChanged(int which) {
    if (ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS == which) {
        // Sync settings have changed; update our in-memory caches
        updateMasterSyncAutomaticallySetting();
        synchronized (mCachedSettings) {
            mCachedSettings.updateSyncSettingsForAccount(
                    ChromeSigninController.get(mApplicationContext).getSignedInUser());
        }
        notifyObservers();
    }
}
 
Example #23
Source File: AutoLoginAccountDelegate.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public boolean logIn() {
    Log.i("AutoLoginAccountDelegate", "auto-login requested for "
            + (mAccount != null ? mAccount.toString() : "?"));

    Account currentAccount = ChromeSigninController.get(mActivity).getSignedInUser();
    if (mAccount == null || !mAccount.equals(currentAccount)) {
        Log.i("InfoBar", "auto-login failed because account is no longer valid");
        return false;
    }

    // The callback for this request comes in on a non-UI thread.
    mAccountManager.getAuthToken(mAccount, mAuthTokenType, null, mActivity, this, null);
    mLogInRequested = true;
    return true;
}
 
Example #24
Source File: SyncController.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private SyncController(Context context) {
    mContext = context;
    mChromeSigninController = ChromeSigninController.get(mContext);
    mSyncStatusHelper = SyncStatusHelper.get(context);
    mSyncStatusHelper.registerSyncSettingsChangedObserver(this);
    mProfileSyncService = ProfileSyncService.get(mContext);
    mProfileSyncService.addSyncStateChangedListener(this);

    setupSessionSyncId();
    mChromeSigninController.ensureGcmIsInitialized();
}
 
Example #25
Source File: AutoLoginAccountDelegate.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public AutoLoginAccountDelegate(Activity activity, AutoLoginProcessor autoLoginProcessor,
        String realm, String account, String accountArgs) {
    mActivity = activity;
    mAutoLoginProcessor = autoLoginProcessor;
    mAccountManager = AccountManager.get(activity);
    mAccount = ChromeSigninController.get(activity).getSignedInUser();
    mLogInRequested = false;
    mAuthTokenType = WEB_LOGIN_PREFIX + accountArgs;
}
 
Example #26
Source File: OAuth2TokenService.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public void validateAccounts(Context context) {
    ThreadUtils.assertOnUiThread();
    String currentlySignedInAccount =
            ChromeSigninController.get(context).getSignedInAccountName();
    String[] accounts = getAccounts(context);
    nativeValidateAccounts(
            mNativeProfileOAuth2TokenService, accounts, currentlySignedInAccount);
}
 
Example #27
Source File: AutoLoginAccountDelegate.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
public AutoLoginAccountDelegate(Activity activity, AutoLoginProcessor autoLoginProcessor,
        String realm, String account, String accountArgs) {
    mActivity = activity;
    mAutoLoginProcessor = autoLoginProcessor;
    mAccountManager = AccountManager.get(activity);
    mAccount = ChromeSigninController.get(activity).getSignedInUser();
    mLogInRequested = false;
    mAuthTokenType = WEB_LOGIN_PREFIX + accountArgs;
}
 
Example #28
Source File: SyncController.java    From android-chromium with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private SyncController(Context context) {
    mContext = context;
    mChromeSigninController = ChromeSigninController.get(mContext);
    mSyncStatusHelper = SyncStatusHelper.get(context);
    mSyncStatusHelper.registerSyncSettingsChangedObserver(this);
    mProfileSyncService = ProfileSyncService.get(mContext);
    mProfileSyncService.addSyncStateChangedListener(this);

    setupSessionSyncId();
    mChromeSigninController.ensureGcmIsInitialized();
}
 
Example #29
Source File: GoogleServicesManager.java    From delion with Apache License 2.0 5 votes vote down vote up
private GoogleServicesManager(Context context) {
    try {
        TraceEvent.begin("GoogleServicesManager.GoogleServicesManager");
        ThreadUtils.assertOnUiThread();
        // We should store the application context, as we outlive any activity which may create
        // us.
        mContext = context.getApplicationContext();

        mChromeSigninController = ChromeSigninController.get(mContext);
        mSigninHelper = SigninHelper.get(mContext);

        // The sign out flow starts by clearing the signed in user in the ChromeSigninController
        // on the Java side, and then performs a sign out on the native side. If there is a
        // crash on the native side then the signin state may get out of sync. Make sure that
        // the native side is signed out if the Java side doesn't have a currently signed in
        // user.
        SigninManager signinManager = SigninManager.get(mContext);
        if (!mChromeSigninController.isSignedIn() && signinManager.isSignedInOnNative()) {
            Log.w(TAG, "Signed in state got out of sync, forcing native sign out");
            signinManager.signOut();
        }

        // Initialize sync.
        SyncController.get(context);

        ApplicationStatus.registerApplicationStateListener(this);
    } finally {
        TraceEvent.end("GoogleServicesManager.GoogleServicesManager");
    }
}
 
Example #30
Source File: InvalidationGcmUpstreamSender.java    From delion with Apache License 2.0 5 votes vote down vote up
@Override
public void deliverMessage(final String to, final Bundle data) {
    @Nullable
    Account account = ChromeSigninController.get(this).getSignedInUser();
    if (account == null) {
        // This should never happen, because this code should only be run if a user is
        // signed-in.
        Log.w(TAG, "No signed-in user; cannot send message to data center");
        return;
    }

    final Bundle dataToSend = createDeepCopy(data);
    final Context applicationContext = getApplicationContext();

    // Attempt to retrieve a token for the user.
    OAuth2TokenService.getOAuth2AccessToken(this, account,
            SyncConstants.CHROME_SYNC_OAUTH2_SCOPE,
            new AccountManagerHelper.GetAuthTokenCallback() {
                @Override
                public void tokenAvailable(final String token) {
                    new AsyncTask<Void, Void, Void>() {
                        @Override
                        protected Void doInBackground(Void... voids) {
                            sendUpstreamMessage(to, dataToSend, token, applicationContext);
                            return null;
                        }
                    }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                }

                @Override
                public void tokenUnavailable(boolean isTransientError) {
                    GcmUma.recordGcmUpstreamHistogram(
                            getApplicationContext(), GcmUma.UMA_UPSTREAM_TOKEN_REQUEST_FAILED);
                }
            });
}