mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
600 lines
24 KiB
Java
600 lines
24 KiB
Java
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.gecko.sync.setup;
|
|
|
|
import java.io.File;
|
|
import java.io.UnsupportedEncodingException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
import org.mozilla.gecko.background.common.GlobalConstants;
|
|
import org.mozilla.gecko.background.common.log.Logger;
|
|
import org.mozilla.gecko.db.BrowserContract;
|
|
import org.mozilla.gecko.sync.CredentialException;
|
|
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
|
import org.mozilla.gecko.sync.SyncConfiguration;
|
|
import org.mozilla.gecko.sync.SyncConstants;
|
|
import org.mozilla.gecko.sync.ThreadPool;
|
|
import org.mozilla.gecko.sync.Utils;
|
|
import org.mozilla.gecko.sync.config.AccountPickler;
|
|
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
|
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.content.ActivityNotFoundException;
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.content.pm.PackageManager.NameNotFoundException;
|
|
import android.os.Bundle;
|
|
import android.provider.Settings;
|
|
import android.util.Log;
|
|
|
|
/**
|
|
* This class contains utilities that are of use to Fennec
|
|
* and Sync setup activities.
|
|
* <p>
|
|
* Do not break these APIs without correcting upstream code!
|
|
*/
|
|
public class SyncAccounts {
|
|
private static final String LOG_TAG = "SyncAccounts";
|
|
|
|
private static final String MOTO_BLUR_SETTINGS_ACTIVITY = "com.motorola.blur.settings.AccountsAndServicesPreferenceActivity";
|
|
private static final String MOTO_BLUR_PACKAGE = "com.motorola.blur.setup";
|
|
|
|
public final static String DEFAULT_SERVER = "https://auth.services.mozilla.com/";
|
|
|
|
/**
|
|
* Return Sync accounts.
|
|
*
|
|
* @param c
|
|
* Android context.
|
|
* @return Sync accounts.
|
|
*/
|
|
public static Account[] syncAccounts(final Context c) {
|
|
return AccountManager.get(c).getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC);
|
|
}
|
|
|
|
/**
|
|
* Returns true if a Sync account is set up, or we have a pickled Sync account
|
|
* on disk that should be un-pickled (Bug 769745). If we have a pickled Sync
|
|
* account, try to un-pickle it and create the corresponding Sync account.
|
|
* <p>
|
|
* Do not call this method from the main thread.
|
|
*/
|
|
public static boolean syncAccountsExist(Context c) {
|
|
final boolean accountsExist = AccountManager.get(c).getAccountsByType(SyncConstants.ACCOUNTTYPE_SYNC).length > 0;
|
|
if (accountsExist) {
|
|
return true;
|
|
}
|
|
|
|
final File file = c.getFileStreamPath(Constants.ACCOUNT_PICKLE_FILENAME);
|
|
if (!file.exists()) {
|
|
return false;
|
|
}
|
|
|
|
// There is a small race window here: if the user creates a new Sync account
|
|
// between our checks, this could erroneously report that no Sync accounts
|
|
// exist.
|
|
final Account account = AccountPickler.unpickle(c, Constants.ACCOUNT_PICKLE_FILENAME);
|
|
return (account != null);
|
|
}
|
|
|
|
/**
|
|
* This class encapsulates the parameters needed to create a new Firefox Sync
|
|
* account.
|
|
*/
|
|
public static class SyncAccountParameters {
|
|
public final Context context;
|
|
public final AccountManager accountManager;
|
|
|
|
|
|
public final String username; // services.sync.account
|
|
public final String syncKey; // in password manager: "chrome://weave (Mozilla Services Encryption Passphrase)"
|
|
public final String password; // in password manager: "chrome://weave (Mozilla Services Password)"
|
|
public final String serverURL; // services.sync.serverURL
|
|
public final String clusterURL; // services.sync.clusterURL
|
|
public final String clientName; // services.sync.client.name
|
|
public final String clientGuid; // services.sync.client.GUID
|
|
|
|
/**
|
|
* Encapsulate the parameters needed to create a new Firefox Sync account.
|
|
*
|
|
* @param context
|
|
* the current <code>Context</code>; cannot be null.
|
|
* @param accountManager
|
|
* an <code>AccountManager</code> instance to use; if null, get it
|
|
* from <code>context</code>.
|
|
* @param username
|
|
* the desired username; cannot be null.
|
|
* @param syncKey
|
|
* the desired sync key; cannot be null.
|
|
* @param password
|
|
* the desired password; cannot be null.
|
|
* @param serverURL
|
|
* the server URL to use; if null, use the default.
|
|
* @param clusterURL
|
|
* the cluster URL to use; if null, a fresh cluster URL will be
|
|
* retrieved from the server during the next sync.
|
|
* @param clientName
|
|
* the client name; if null, a fresh client record will be uploaded
|
|
* to the server during the next sync.
|
|
* @param clientGuid
|
|
* the client GUID; if null, a fresh client record will be uploaded
|
|
* to the server during the next sync.
|
|
*/
|
|
public SyncAccountParameters(Context context, AccountManager accountManager,
|
|
String username, String syncKey, String password,
|
|
String serverURL, String clusterURL,
|
|
String clientName, String clientGuid) {
|
|
if (context == null) {
|
|
throw new IllegalArgumentException("Null context passed to SyncAccountParameters constructor.");
|
|
}
|
|
if (username == null) {
|
|
throw new IllegalArgumentException("Null username passed to SyncAccountParameters constructor.");
|
|
}
|
|
if (syncKey == null) {
|
|
throw new IllegalArgumentException("Null syncKey passed to SyncAccountParameters constructor.");
|
|
}
|
|
if (password == null) {
|
|
throw new IllegalArgumentException("Null password passed to SyncAccountParameters constructor.");
|
|
}
|
|
this.context = context;
|
|
this.accountManager = accountManager;
|
|
this.username = username;
|
|
this.syncKey = syncKey;
|
|
this.password = password;
|
|
this.serverURL = serverURL;
|
|
this.clusterURL = clusterURL;
|
|
this.clientName = clientName;
|
|
this.clientGuid = clientGuid;
|
|
}
|
|
|
|
public SyncAccountParameters(Context context, AccountManager accountManager,
|
|
String username, String syncKey, String password, String serverURL) {
|
|
this(context, accountManager, username, syncKey, password, serverURL, null, null, null);
|
|
}
|
|
|
|
public SyncAccountParameters(final Context context, final AccountManager accountManager, final ExtendedJSONObject o) {
|
|
this(context, accountManager,
|
|
o.getString(Constants.JSON_KEY_ACCOUNT),
|
|
o.getString(Constants.JSON_KEY_SYNCKEY),
|
|
o.getString(Constants.JSON_KEY_PASSWORD),
|
|
o.getString(Constants.JSON_KEY_SERVER),
|
|
o.getString(Constants.JSON_KEY_CLUSTER),
|
|
o.getString(Constants.JSON_KEY_CLIENT_NAME),
|
|
o.getString(Constants.JSON_KEY_CLIENT_GUID));
|
|
}
|
|
|
|
public ExtendedJSONObject asJSON() {
|
|
final ExtendedJSONObject o = new ExtendedJSONObject();
|
|
o.put(Constants.JSON_KEY_ACCOUNT, username);
|
|
o.put(Constants.JSON_KEY_PASSWORD, password);
|
|
o.put(Constants.JSON_KEY_SERVER, serverURL);
|
|
o.put(Constants.JSON_KEY_SYNCKEY, syncKey);
|
|
o.put(Constants.JSON_KEY_CLUSTER, clusterURL);
|
|
o.put(Constants.JSON_KEY_CLIENT_NAME, clientName);
|
|
o.put(Constants.JSON_KEY_CLIENT_GUID, clientGuid);
|
|
return o;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a sync account, clearing any existing preferences, and set it to
|
|
* sync automatically.
|
|
* <p>
|
|
* Do not call this method from the main thread.
|
|
*
|
|
* @param syncAccount
|
|
* parameters of the account to be created.
|
|
* @return created <code>Account</code>, or null if an error occurred and the
|
|
* account could not be added.
|
|
*/
|
|
public static Account createSyncAccount(SyncAccountParameters syncAccount) {
|
|
return createSyncAccount(syncAccount, true, true);
|
|
}
|
|
|
|
/**
|
|
* Create a sync account, clearing any existing preferences.
|
|
* <p>
|
|
* Do not call this method from the main thread.
|
|
* <p>
|
|
* Intended for testing; use
|
|
* <code>createSyncAccount(SyncAccountParameters)</code> instead.
|
|
*
|
|
* @param syncAccount
|
|
* parameters of the account to be created.
|
|
* @param syncAutomatically
|
|
* whether to start syncing this Account automatically (
|
|
* <code>false</code> for test accounts).
|
|
* @return created Android <code>Account</code>, or null if an error occurred
|
|
* and the account could not be added.
|
|
*/
|
|
public static Account createSyncAccount(SyncAccountParameters syncAccount,
|
|
boolean syncAutomatically) {
|
|
return createSyncAccount(syncAccount, syncAutomatically, true);
|
|
}
|
|
|
|
public static Account createSyncAccountPreservingExistingPreferences(SyncAccountParameters syncAccount,
|
|
boolean syncAutomatically) {
|
|
return createSyncAccount(syncAccount, syncAutomatically, false);
|
|
}
|
|
|
|
/**
|
|
* Create a sync account.
|
|
* <p>
|
|
* Do not call this method from the main thread.
|
|
* <p>
|
|
* Intended for testing; use
|
|
* <code>createSyncAccount(SyncAccountParameters)</code> instead.
|
|
*
|
|
* @param syncAccount
|
|
* parameters of the account to be created.
|
|
* @param syncAutomatically
|
|
* whether to start syncing this Account automatically (
|
|
* <code>false</code> for test accounts).
|
|
* @param clearPreferences
|
|
* <code>true</code> to clear existing preferences before creating.
|
|
* @return created Android <code>Account</code>, or null if an error occurred
|
|
* and the account could not be added.
|
|
*/
|
|
protected static Account createSyncAccount(SyncAccountParameters syncAccount,
|
|
boolean syncAutomatically, boolean clearPreferences) {
|
|
final Context context = syncAccount.context;
|
|
final AccountManager accountManager = (syncAccount.accountManager == null) ?
|
|
AccountManager.get(syncAccount.context) : syncAccount.accountManager;
|
|
final String username = syncAccount.username;
|
|
final String syncKey = syncAccount.syncKey;
|
|
final String password = syncAccount.password;
|
|
final String serverURL = (syncAccount.serverURL == null) ?
|
|
DEFAULT_SERVER : syncAccount.serverURL;
|
|
|
|
Logger.debug(LOG_TAG, "Using account manager " + accountManager);
|
|
if (!RepoUtils.stringsEqual(syncAccount.serverURL, DEFAULT_SERVER)) {
|
|
Logger.info(LOG_TAG, "Setting explicit server URL: " + serverURL);
|
|
}
|
|
|
|
final Account account = new Account(username, SyncConstants.ACCOUNTTYPE_SYNC);
|
|
final Bundle userbundle = new Bundle();
|
|
|
|
// Add sync key and server URL.
|
|
userbundle.putString(Constants.OPTION_SYNCKEY, syncKey);
|
|
userbundle.putString(Constants.OPTION_SERVER, serverURL);
|
|
Logger.debug(LOG_TAG, "Adding account for " + SyncConstants.ACCOUNTTYPE_SYNC);
|
|
boolean result = false;
|
|
try {
|
|
result = accountManager.addAccountExplicitly(account, password, userbundle);
|
|
} catch (SecurityException e) {
|
|
// We use Log rather than Logger here to avoid possibly hiding these errors.
|
|
final String message = e.getMessage();
|
|
if (message != null && (message.indexOf("is different than the authenticator's uid") > 0)) {
|
|
Log.wtf(SyncConstants.GLOBAL_LOG_TAG,
|
|
"Unable to create account. " +
|
|
"If you have more than one version of " +
|
|
"Firefox/Beta/Aurora/Nightly/Fennec installed, that's why.",
|
|
e);
|
|
} else {
|
|
Log.e(SyncConstants.GLOBAL_LOG_TAG, "Unable to create account.", e);
|
|
}
|
|
}
|
|
|
|
if (!result) {
|
|
Logger.error(LOG_TAG, "Failed to add account " + account + "!");
|
|
return null;
|
|
}
|
|
Logger.debug(LOG_TAG, "Account " + account + " added successfully.");
|
|
|
|
setSyncAutomatically(account, syncAutomatically);
|
|
setIsSyncable(account, syncAutomatically);
|
|
Logger.debug(LOG_TAG, "Set account to sync automatically? " + syncAutomatically + ".");
|
|
|
|
try {
|
|
final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
|
|
final String profile = Constants.DEFAULT_PROFILE;
|
|
final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
|
|
|
|
final SharedPreferences.Editor editor = Utils.getSharedPreferences(context, product, username, serverURL, profile, version).edit();
|
|
if (clearPreferences) {
|
|
final String prefsPath = Utils.getPrefsPath(product, username, serverURL, profile, version);
|
|
Logger.info(LOG_TAG, "Clearing preferences path " + prefsPath + " for this account.");
|
|
editor.clear();
|
|
}
|
|
|
|
if (syncAccount.clusterURL != null) {
|
|
editor.putString(SyncConfiguration.PREF_CLUSTER_URL, syncAccount.clusterURL);
|
|
}
|
|
|
|
if (syncAccount.clientName != null && syncAccount.clientGuid != null) {
|
|
Logger.debug(LOG_TAG, "Setting client name to " + syncAccount.clientName + " and client GUID to " + syncAccount.clientGuid + ".");
|
|
editor.putString(SyncConfiguration.PREF_CLIENT_NAME, syncAccount.clientName);
|
|
editor.putString(SyncConfiguration.PREF_ACCOUNT_GUID, syncAccount.clientGuid);
|
|
} else {
|
|
Logger.debug(LOG_TAG, "Client name and guid not both non-null, so not setting client data.");
|
|
}
|
|
|
|
editor.commit();
|
|
} catch (Exception e) {
|
|
Logger.error(LOG_TAG, "Could not clear prefs path!", e);
|
|
}
|
|
return account;
|
|
}
|
|
|
|
public static void setIsSyncable(Account account, boolean isSyncable) {
|
|
String authority = BrowserContract.AUTHORITY;
|
|
ContentResolver.setIsSyncable(account, authority, isSyncable ? 1 : 0);
|
|
}
|
|
|
|
public static void setSyncAutomatically(Account account, boolean syncAutomatically) {
|
|
if (syncAutomatically) {
|
|
ContentResolver.setMasterSyncAutomatically(true);
|
|
}
|
|
|
|
String authority = BrowserContract.AUTHORITY;
|
|
Logger.debug(LOG_TAG, "Setting authority " + authority + " to " +
|
|
(syncAutomatically ? "" : "not ") + "sync automatically.");
|
|
ContentResolver.setSyncAutomatically(account, authority, syncAutomatically);
|
|
}
|
|
|
|
public static void backgroundSetSyncAutomatically(final Account account, final boolean syncAutomatically) {
|
|
ThreadPool.run(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
setSyncAutomatically(account, syncAutomatically);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Bug 721760: try to start a vendor-specific Accounts & Sync activity on Moto
|
|
* Blur devices.
|
|
* <p>
|
|
* Bug 773562: actually start and catch <code>ActivityNotFoundException</code>,
|
|
* rather than just returning the <code>Intent</code> only, because some
|
|
* Moto devices fail to start the activity.
|
|
*
|
|
* @param context
|
|
* current Android context.
|
|
* @param vendorPackage
|
|
* vendor specific package name.
|
|
* @param vendorClass
|
|
* vendor specific class name.
|
|
* @return null on failure, otherwise the <code>Intent</code> started.
|
|
*/
|
|
protected static Intent openVendorSyncSettings(Context context, final String vendorPackage, final String vendorClass) {
|
|
try {
|
|
final int contextFlags = Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY;
|
|
Context foreignContext = context.createPackageContext(vendorPackage, contextFlags);
|
|
Class<?> klass = foreignContext.getClassLoader().loadClass(vendorClass);
|
|
|
|
final Intent intent = new Intent(foreignContext, klass);
|
|
context.startActivity(intent);
|
|
Logger.info(LOG_TAG, "Vendor package " + vendorPackage + " and class " +
|
|
vendorClass + " found, and activity launched.");
|
|
return intent;
|
|
} catch (NameNotFoundException e) {
|
|
Logger.debug(LOG_TAG, "Vendor package " + vendorPackage + " not found. Skipping.");
|
|
} catch (ClassNotFoundException e) {
|
|
Logger.debug(LOG_TAG, "Vendor package " + vendorPackage + " found but class " +
|
|
vendorClass + " not found. Skipping.", e);
|
|
} catch (ActivityNotFoundException e) {
|
|
// Bug 773562 - android.content.ActivityNotFoundException on Motorola devices.
|
|
Logger.warn(LOG_TAG, "Vendor package " + vendorPackage + " and class " +
|
|
vendorClass + " found, but activity not launched. Skipping.", e);
|
|
} catch (Exception e) {
|
|
// Just in case.
|
|
Logger.warn(LOG_TAG, "Caught exception launching activity from vendor package " + vendorPackage +
|
|
" and class " + vendorClass + ". Ignoring.", e);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Start Sync settings activity.
|
|
*
|
|
* @param context
|
|
* current Android context.
|
|
* @return the <code>Intent</code> started.
|
|
*/
|
|
public static Intent openSyncSettings(Context context) {
|
|
// Bug 721760 - opening Sync settings takes user to Battery & Data Manager
|
|
// on a variety of Motorola devices. This work around tries to load the
|
|
// correct Intent by hand. Oh, Android.
|
|
Intent intent = openVendorSyncSettings(context, MOTO_BLUR_PACKAGE, MOTO_BLUR_SETTINGS_ACTIVITY);
|
|
if (intent != null) {
|
|
return intent;
|
|
}
|
|
|
|
// Open default Sync settings activity.
|
|
intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
|
|
// Bug 774233: do not start activity as a new task (second run fails on some HTC devices).
|
|
context.startActivity(intent); // We should always find this Activity.
|
|
return intent;
|
|
}
|
|
|
|
/**
|
|
* Synchronously extract Sync account parameters from Android account version
|
|
* 0, using plain auth token type.
|
|
* <p>
|
|
* Safe to call from main thread.
|
|
*
|
|
* @param context
|
|
* Android context.
|
|
* @param accountManager
|
|
* Android account manager.
|
|
* @param account
|
|
* Android Account.
|
|
* @return Sync account parameters, always non-null; fields username,
|
|
* password, serverURL, and syncKey always non-null.
|
|
*/
|
|
public static SyncAccountParameters blockingFromAndroidAccountV0(final Context context, final AccountManager accountManager, final Account account)
|
|
throws CredentialException {
|
|
String username;
|
|
try {
|
|
username = Utils.usernameFromAccount(account.name);
|
|
} catch (NoSuchAlgorithmException e) {
|
|
throw new CredentialException.MissingCredentialException("username");
|
|
} catch (UnsupportedEncodingException e) {
|
|
throw new CredentialException.MissingCredentialException("username");
|
|
}
|
|
|
|
/*
|
|
* If we are accessing an Account that we don't own, Android will throw an
|
|
* unchecked <code>SecurityException</code> saying
|
|
* "W FxSync(XXXX) java.lang.SecurityException: caller uid XXXXX is different than the authenticator's uid".
|
|
* We catch that error and throw accordingly.
|
|
*/
|
|
String password;
|
|
String syncKey;
|
|
String serverURL;
|
|
try {
|
|
password = accountManager.getPassword(account);
|
|
syncKey = accountManager.getUserData(account, Constants.OPTION_SYNCKEY);
|
|
serverURL = accountManager.getUserData(account, Constants.OPTION_SERVER);
|
|
} catch (SecurityException e) {
|
|
Logger.warn(LOG_TAG, "Got security exception fetching Sync account parameters; throwing.");
|
|
throw new CredentialException.MissingAllCredentialsException(e);
|
|
}
|
|
|
|
if (password == null &&
|
|
username == null &&
|
|
syncKey == null &&
|
|
serverURL == null) {
|
|
throw new CredentialException.MissingAllCredentialsException();
|
|
}
|
|
|
|
if (password == null) {
|
|
throw new CredentialException.MissingCredentialException("password");
|
|
}
|
|
|
|
if (syncKey == null) {
|
|
throw new CredentialException.MissingCredentialException("syncKey");
|
|
}
|
|
|
|
if (serverURL == null) {
|
|
throw new CredentialException.MissingCredentialException("serverURL");
|
|
}
|
|
|
|
try {
|
|
// SyncAccountParameters constructor throws on null inputs. This shouldn't
|
|
// happen, but let's be safe.
|
|
return new SyncAccountParameters(context, accountManager, username, syncKey, password, serverURL);
|
|
} catch (Exception e) {
|
|
Logger.warn(LOG_TAG, "Got exception fetching Sync account parameters; throwing.");
|
|
throw new CredentialException.MissingAllCredentialsException(e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Bug 790931: create an intent announcing that a Sync account will be
|
|
* deleted.
|
|
* <p>
|
|
* This intent <b>must</b> be broadcast with secure permissions, because it
|
|
* contains sensitive user information including the Sync account password and
|
|
* Sync key.
|
|
* <p>
|
|
* Version 1 of the created intent includes extras with keys
|
|
* <code>Constants.JSON_KEY_VERSION</code>,
|
|
* <code>Constants.JSON_KEY_TIMESTAMP</code>, and
|
|
* <code>Constants.JSON_KEY_ACCOUNT</code> (which is the Android Account name,
|
|
* not the encoded Sync Account name).
|
|
* <p>
|
|
* If possible, it contains the key <code>Constants.JSON_KEY_PAYLOAD</code>
|
|
* with value the Sync account parameters as JSON, <b>except the Sync key has
|
|
* been replaced with the empty string</b>. (We replace, rather than remove,
|
|
* the Sync key because SyncAccountParameters expects a non-null Sync key.)
|
|
*
|
|
* @see SyncAccountParameters#asJSON
|
|
*
|
|
* @param context
|
|
* Android context.
|
|
* @param accountManager
|
|
* Android account manager.
|
|
* @param account
|
|
* Android account being removed.
|
|
* @return <code>Intent</code> to broadcast.
|
|
*/
|
|
public static Intent makeSyncAccountDeletedIntent(final Context context, final AccountManager accountManager, final Account account) {
|
|
final Intent intent = new Intent(SyncConstants.SYNC_ACCOUNT_DELETED_ACTION);
|
|
|
|
intent.putExtra(Constants.JSON_KEY_VERSION, Long.valueOf(SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION));
|
|
intent.putExtra(Constants.JSON_KEY_TIMESTAMP, Long.valueOf(System.currentTimeMillis()));
|
|
intent.putExtra(Constants.JSON_KEY_ACCOUNT, account.name);
|
|
|
|
SyncAccountParameters accountParameters = null;
|
|
try {
|
|
accountParameters = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
|
|
} catch (Exception e) {
|
|
Logger.warn(LOG_TAG, "Caught exception fetching account parameters.", e);
|
|
}
|
|
|
|
if (accountParameters != null) {
|
|
ExtendedJSONObject json = accountParameters.asJSON();
|
|
json.put(Constants.JSON_KEY_SYNCKEY, ""); // Reduce attack surface area by removing Sync key.
|
|
intent.putExtra(Constants.JSON_KEY_PAYLOAD, json.toJSONString());
|
|
}
|
|
|
|
return intent;
|
|
}
|
|
|
|
/**
|
|
* Synchronously fetch SharedPreferences of a profile associated with a Sync
|
|
* account.
|
|
* <p>
|
|
* Safe to call from main thread.
|
|
*
|
|
* @param context
|
|
* Android context.
|
|
* @param accountManager
|
|
* Android account manager.
|
|
* @param account
|
|
* Android Account.
|
|
* @param product
|
|
* package.
|
|
* @param profile
|
|
* of account.
|
|
* @param version
|
|
* number.
|
|
* @return SharedPreferences associated with Sync account.
|
|
* @throws CredentialException
|
|
* @throws NoSuchAlgorithmException
|
|
* @throws UnsupportedEncodingException
|
|
*/
|
|
public static SharedPreferences blockingPrefsFromAndroidAccountV0(final Context context, final AccountManager accountManager, final Account account,
|
|
final String product, final String profile, final long version)
|
|
throws CredentialException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
|
SyncAccountParameters params = SyncAccounts.blockingFromAndroidAccountV0(context, accountManager, account);
|
|
String prefsPath = Utils.getPrefsPath(product, params.username, params.serverURL, profile, version);
|
|
|
|
return context.getSharedPreferences(prefsPath, Utils.SHARED_PREFERENCES_MODE);
|
|
}
|
|
|
|
/**
|
|
* Synchronously fetch SharedPreferences of a profile associated with the
|
|
* default Firefox profile of a Sync Account.
|
|
* <p>
|
|
* Uses the default package, default profile, and current version.
|
|
* <p>
|
|
* Safe to call from main thread.
|
|
*
|
|
* @param context
|
|
* Android context.
|
|
* @param accountManager
|
|
* Android account manager.
|
|
* @param account
|
|
* Android Account.
|
|
* @return SharedPreferences associated with Sync account.
|
|
* @throws CredentialException
|
|
* @throws NoSuchAlgorithmException
|
|
* @throws UnsupportedEncodingException
|
|
*/
|
|
public static SharedPreferences blockingPrefsFromDefaultProfileV0(final Context context, final AccountManager accountManager, final Account account)
|
|
throws CredentialException, NoSuchAlgorithmException, UnsupportedEncodingException {
|
|
final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
|
|
final String profile = Constants.DEFAULT_PROFILE;
|
|
final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
|
|
|
|
return blockingPrefsFromAndroidAccountV0(context, accountManager, account, product, profile, version);
|
|
}
|
|
}
|