mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 769745 - Persist Android Sync account settings to disk on each sync and re-create account when checking if Sync is set up. r=rnewman
This commit is contained in:
parent
ac853e9899
commit
e27ca6cd41
File diff suppressed because one or more lines are too long
@ -4,6 +4,10 @@
|
||||
|
||||
package org.mozilla.gecko.sync;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
@ -441,4 +445,50 @@ public class Utils {
|
||||
bundle.putString(Constants.EXTRAS_KEY_STAGES_TO_SKIP, o.toJSONString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read contents of file as a string.
|
||||
*
|
||||
* @param context Android context.
|
||||
* @param filename name of file to read; must not be null.
|
||||
* @return <code>String</code> instance.
|
||||
*/
|
||||
public static String readFile(final Context context, final String filename) {
|
||||
if (filename == null) {
|
||||
throw new IllegalArgumentException("Passed null filename in readFile.");
|
||||
}
|
||||
|
||||
FileInputStream fis = null;
|
||||
InputStreamReader isr = null;
|
||||
BufferedReader br = null;
|
||||
|
||||
try {
|
||||
fis = context.openFileInput(filename);
|
||||
isr = new InputStreamReader(fis);
|
||||
br = new BufferedReader(isr);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
} finally {
|
||||
if (isr != null) {
|
||||
try {
|
||||
isr.close();
|
||||
} catch (IOException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
if (fis != null) {
|
||||
try {
|
||||
fis.close();
|
||||
} catch (IOException e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
159
mobile/android/base/sync/config/AccountPickler.java
Normal file
159
mobile/android/base/sync/config/AccountPickler.java
Normal file
@ -0,0 +1,159 @@
|
||||
/* 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.config;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Bug 768102: Android deletes Account objects when the Authenticator that owns
|
||||
* the Account disappears. This happens when an App is installed to the SD card
|
||||
* and the SD card is un-mounted.
|
||||
* <p>
|
||||
* Bug 769745: We work around this by pickling the current Sync account data
|
||||
* every sync and un-pickling when we check if Sync accounts exist (called from
|
||||
* Fennec).
|
||||
*/
|
||||
public class AccountPickler {
|
||||
public static final String LOG_TAG = "AccountPickler";
|
||||
|
||||
public static final long VERSION = 1;
|
||||
|
||||
/**
|
||||
* Remove Sync account persisted to disk.
|
||||
*
|
||||
* @param context Android context.
|
||||
* @param filename name of persisted pickle file; must not contain path separators.
|
||||
* @return <code>true</code> if given pickle existed and was successfully deleted.
|
||||
*/
|
||||
public static boolean deletePickle(final Context context, final String filename) {
|
||||
return context.deleteFile(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist Sync account to disk as a JSON object.
|
||||
* <p>
|
||||
* JSON object has keys:
|
||||
* <ul>
|
||||
* <li><code>Constants.JSON_KEY_ACCOUNT</code>: the Sync account's un-encoded username,
|
||||
* like "test@mozilla.com".</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_PASSWORD</code>: the Sync account's password;</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_SERVER</code>: the Sync account's server;</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_SYNCKEY</code>: the Sync account's sync key;</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_CLUSTER</code>: the Sync account's cluster (may be null);</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_CLIENT_NAME</code>: the Sync account's client name (may be null);</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_CLIENT_GUID</code>: the Sync account's client GUID (may be null);</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_SYNC_AUTOMATICALLY</code>: true if the Android Account is syncing automically;</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_VERSION</code>: version of this file;</li>
|
||||
*
|
||||
* <li><code>Constants.JSON_KEY_TIMESTAMP</code>: when this file was written.</li>
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @param context Android context.
|
||||
* @param filename name of file to persist to; must not contain path separators.
|
||||
* @param params the Sync account's parameters.
|
||||
* @param syncAutomatically whether the Android Account object is syncing automatically.
|
||||
*/
|
||||
public static void pickle(final Context context, final String filename,
|
||||
final SyncAccountParameters params, final boolean syncAutomatically) {
|
||||
final ExtendedJSONObject o = params.asJSON();
|
||||
o.put(Constants.JSON_KEY_SYNC_AUTOMATICALLY, new Boolean(syncAutomatically));
|
||||
o.put(Constants.JSON_KEY_VERSION, new Long(VERSION));
|
||||
o.put(Constants.JSON_KEY_TIMESTAMP, new Long(System.currentTimeMillis()));
|
||||
|
||||
PrintStream ps = null;
|
||||
try {
|
||||
final FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
|
||||
ps = new PrintStream(fos);
|
||||
ps.print(o.toJSONString());
|
||||
Logger.debug(LOG_TAG, "Persisted " + o.keySet().size() + " account settings to " + filename + ".");
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Caught exception persisting account settings to " + filename + "; ignoring.", e);
|
||||
} finally {
|
||||
if (ps != null) {
|
||||
ps.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Android account from saved JSON object.
|
||||
*
|
||||
* @param context
|
||||
* Android context.
|
||||
* @param filename
|
||||
* name of file to read from; must not contain path separators.
|
||||
* @return created Android account, or null on error.
|
||||
*/
|
||||
public static Account unpickle(final Context context, final String filename) {
|
||||
final String jsonString = Utils.readFile(context, filename);
|
||||
if (jsonString == null) {
|
||||
Logger.info(LOG_TAG, "Pickle file '" + filename + "' not found; aborting.");
|
||||
return null;
|
||||
}
|
||||
|
||||
ExtendedJSONObject json = null;
|
||||
try {
|
||||
json = ExtendedJSONObject.parseJSONObject(jsonString);
|
||||
} catch (Exception e) {
|
||||
Logger.warn(LOG_TAG, "Got exception reading pickle file '" + filename + "'; aborting.", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
SyncAccountParameters params = null;
|
||||
try {
|
||||
// Null checking of inputs is done in constructor.
|
||||
params = new SyncAccountParameters(context, null, json);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logger.warn(LOG_TAG, "Un-pickled data included null username, password, or serverURL; aborting.", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Default to syncing automatically.
|
||||
boolean syncAutomatically = true;
|
||||
if (json.containsKey(Constants.JSON_KEY_SYNC_AUTOMATICALLY)) {
|
||||
if ((new Boolean(false)).equals(json.get(Constants.JSON_KEY_SYNC_AUTOMATICALLY))) {
|
||||
syncAutomatically = false;
|
||||
}
|
||||
}
|
||||
|
||||
final Account account = SyncAccounts.createSyncAccountPreservingExistingPreferences(params, syncAutomatically);
|
||||
if (account == null) {
|
||||
Logger.warn(LOG_TAG, "Failed to add Android Account; aborting.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer version = json.getIntegerSafely(Constants.JSON_KEY_VERSION);
|
||||
Integer timestamp = json.getIntegerSafely(Constants.JSON_KEY_TIMESTAMP);
|
||||
if (version == null || timestamp == null) {
|
||||
Logger.warn(LOG_TAG, "Did not find version or timestamp in pickle file; ignoring.");
|
||||
version = new Integer(-1);
|
||||
timestamp = new Integer(-1);
|
||||
}
|
||||
|
||||
Logger.info(LOG_TAG, "Un-pickled Android account named " + params.username + " (version " + version + ", pickled at " + timestamp + ").");
|
||||
|
||||
return account;
|
||||
}
|
||||
}
|
@ -18,6 +18,13 @@ public class Constants {
|
||||
public static final String NUM_CLIENTS = "account.numClients";
|
||||
public static final String DATA_ENABLE_ON_UPGRADE = "data.enableOnUpgrade";
|
||||
|
||||
/**
|
||||
* Name of file to pickle current account preferences to each sync.
|
||||
* <p>
|
||||
* Must not contain path separators!
|
||||
*/
|
||||
public static final String ACCOUNT_PICKLE_FILENAME = "sync.account.json";
|
||||
|
||||
/**
|
||||
* Key in sync extras bundle specifying stages to sync this sync session.
|
||||
* <p>
|
||||
@ -73,6 +80,11 @@ public class Constants {
|
||||
public static final String JSON_KEY_PASSWORD = "password";
|
||||
public static final String JSON_KEY_SYNCKEY = "synckey";
|
||||
public static final String JSON_KEY_SERVER = "serverURL";
|
||||
public static final String JSON_KEY_CLUSTER = "clusterURL";
|
||||
public static final String JSON_KEY_CLIENT_NAME = "clientName";
|
||||
public static final String JSON_KEY_CLIENT_GUID = "clientGUID";
|
||||
public static final String JSON_KEY_SYNC_AUTOMATICALLY = "syncAutomatically";
|
||||
public static final String JSON_KEY_TIMESTAMP = "timestamp";
|
||||
|
||||
public static final String CRYPTO_KEY_GR1 = "gr1";
|
||||
public static final String CRYPTO_KEY_GR2 = "gr2";
|
||||
|
@ -4,10 +4,14 @@
|
||||
|
||||
package org.mozilla.gecko.sync.setup;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.SyncConfiguration;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.config.AccountPickler;
|
||||
import org.mozilla.gecko.sync.repositories.android.RepoUtils;
|
||||
import org.mozilla.gecko.sync.syncadapter.SyncAdapter;
|
||||
|
||||
@ -38,12 +42,28 @@ public class SyncAccounts {
|
||||
public final static String DEFAULT_SERVER = "https://auth.services.mozilla.com/";
|
||||
|
||||
/**
|
||||
* Returns true if a Sync account is set up.
|
||||
* 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) {
|
||||
return AccountManager.get(c).getAccountsByType(Constants.ACCOUNTTYPE_SYNC).length > 0;
|
||||
final boolean accountsExist = AccountManager.get(c).getAccountsByType(Constants.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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,6 +154,29 @@ public class SyncAccounts {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,11 +188,21 @@ public class SyncAccounts {
|
||||
* occurred and the account could not be added.
|
||||
*/
|
||||
public static class CreateSyncAccountTask extends AsyncTask<SyncAccountParameters, Void, Account> {
|
||||
protected final boolean syncAutomatically;
|
||||
|
||||
public CreateSyncAccountTask() {
|
||||
this(true);
|
||||
}
|
||||
|
||||
public CreateSyncAccountTask(final boolean syncAutomically) {
|
||||
this.syncAutomatically = syncAutomically;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Account doInBackground(SyncAccountParameters... params) {
|
||||
SyncAccountParameters syncAccount = params[0];
|
||||
try {
|
||||
return createSyncAccount(syncAccount);
|
||||
return createSyncAccount(syncAccount, syncAutomatically);
|
||||
} catch (Exception e) {
|
||||
Log.e(Logger.GLOBAL_LOG_TAG, "Unable to create account.", e);
|
||||
return null;
|
||||
@ -158,16 +211,66 @@ public class SyncAccounts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sync account.
|
||||
* 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
|
||||
* The parameters of the account to be created.
|
||||
* @return The created <code>Account</code>, or null if an error occurred and
|
||||
* the account could not be added.
|
||||
* 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;
|
||||
@ -212,7 +315,10 @@ public class SyncAccounts {
|
||||
}
|
||||
Logger.debug(LOG_TAG, "Account " + account + " added successfully.");
|
||||
|
||||
setSyncAutomatically(account);
|
||||
setSyncAutomatically(account, syncAutomatically);
|
||||
setIsSyncable(account, syncAutomatically);
|
||||
Logger.debug(LOG_TAG, "Set account to sync automatically? " + syncAutomatically + ".");
|
||||
|
||||
setClientRecord(context, accountManager, account, syncAccount.clientName, syncAccount.clientGuid);
|
||||
|
||||
// TODO: add other ContentProviders as needed (e.g. passwords)
|
||||
@ -221,12 +327,17 @@ public class SyncAccounts {
|
||||
|
||||
// Purging global prefs assumes we have only a single Sync account at one time.
|
||||
// TODO: Bug 761682: don't do anything with global prefs here.
|
||||
Logger.info(LOG_TAG, "Clearing global prefs.");
|
||||
SyncAdapter.purgeGlobalPrefs(context);
|
||||
if (clearPreferences) {
|
||||
Logger.info(LOG_TAG, "Clearing global prefs.");
|
||||
SyncAdapter.purgeGlobalPrefs(context);
|
||||
}
|
||||
|
||||
try {
|
||||
Logger.info(LOG_TAG, "Clearing preferences path " + Utils.getPrefsPath(username, serverURL) + " for this account.");
|
||||
SharedPreferences.Editor editor = Utils.getSharedPreferences(context, username, serverURL).edit().clear();
|
||||
SharedPreferences.Editor editor = Utils.getSharedPreferences(context, username, serverURL).edit();
|
||||
if (clearPreferences) {
|
||||
Logger.info(LOG_TAG, "Clearing preferences path " + Utils.getPrefsPath(username, serverURL) + " for this account.");
|
||||
editor.clear();
|
||||
}
|
||||
if (syncAccount.clusterURL != null) {
|
||||
editor.putString(SyncConfiguration.PREF_CLUSTER_URL, syncAccount.clusterURL);
|
||||
}
|
||||
@ -253,11 +364,6 @@ public class SyncAccounts {
|
||||
ContentResolver.setSyncAutomatically(account, authority, syncAutomatically);
|
||||
}
|
||||
|
||||
public static void setSyncAutomatically(Account account) {
|
||||
setSyncAutomatically(account, true);
|
||||
setIsSyncable(account, true);
|
||||
}
|
||||
|
||||
public static Intent openSyncSettings(Context context) {
|
||||
Intent intent = null;
|
||||
|
||||
|
@ -9,6 +9,7 @@ import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.mozilla.gecko.sync.Logger;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.config.AccountPickler;
|
||||
import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
|
||||
|
||||
import android.accounts.AbstractAccountAuthenticator;
|
||||
@ -160,5 +161,35 @@ public class SyncAuthenticatorService extends Service {
|
||||
Logger.debug(LOG_TAG, "updateCredentials()");
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug 769745: persist pickled Sync account settings so that we can unpickle
|
||||
* after Fennec is moved to the SD card.
|
||||
* <p>
|
||||
* This is <b>not</b> called when an Android Account is blown away due to the
|
||||
* SD card being unmounted.
|
||||
* <p>
|
||||
* This is a terrible hack, but it's better than the catching the generic
|
||||
* "accounts changed" broadcast intent and trying to figure out whether our
|
||||
* Account disappeared.
|
||||
*/
|
||||
@Override
|
||||
public Bundle getAccountRemovalAllowed(AccountAuthenticatorResponse response, Account account) throws NetworkErrorException {
|
||||
Bundle result = super.getAccountRemovalAllowed(response, account);
|
||||
|
||||
if (result != null &&
|
||||
result.containsKey(AccountManager.KEY_BOOLEAN_RESULT) &&
|
||||
!result.containsKey(AccountManager.KEY_INTENT)) {
|
||||
final boolean removalAllowed = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
|
||||
|
||||
if (removalAllowed) {
|
||||
Logger.info(LOG_TAG, "Account named " + account.name + " being removed; " +
|
||||
"deleting saved pickle file '" + Constants.ACCOUNT_PICKLE_FILENAME + "'.");
|
||||
AccountPickler.deletePickle(mContext, Constants.ACCOUNT_PICKLE_FILENAME);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,12 +21,15 @@ import org.mozilla.gecko.sync.SyncConfigurationException;
|
||||
import org.mozilla.gecko.sync.SyncException;
|
||||
import org.mozilla.gecko.sync.ThreadPool;
|
||||
import org.mozilla.gecko.sync.Utils;
|
||||
import org.mozilla.gecko.sync.config.AccountPickler;
|
||||
import org.mozilla.gecko.sync.crypto.CryptoException;
|
||||
import org.mozilla.gecko.sync.crypto.KeyBundle;
|
||||
import org.mozilla.gecko.sync.delegates.ClientsDataDelegate;
|
||||
import org.mozilla.gecko.sync.delegates.GlobalSessionCallback;
|
||||
import org.mozilla.gecko.sync.net.ConnectionMonitorThread;
|
||||
import org.mozilla.gecko.sync.setup.Constants;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts;
|
||||
import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
|
||||
import org.mozilla.gecko.sync.stage.GlobalSyncStage.Stage;
|
||||
|
||||
import android.accounts.Account;
|
||||
@ -341,13 +344,11 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe
|
||||
return;
|
||||
}
|
||||
|
||||
KeyBundle keyBundle = new KeyBundle(username, syncKey);
|
||||
|
||||
// Support multiple accounts by mapping each server/account pair to a branch of the
|
||||
// shared preferences space.
|
||||
String prefsPath = Utils.getPrefsPath(username, serverURL);
|
||||
self.performSync(account, extras, authority, provider, syncResult,
|
||||
username, password, prefsPath, serverURL, keyBundle);
|
||||
username, password, prefsPath, serverURL, syncKey);
|
||||
} catch (Exception e) {
|
||||
self.handleException(e, syncResult);
|
||||
return;
|
||||
@ -413,22 +414,47 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe
|
||||
* @throws NonObjectJSONException
|
||||
* @throws ParseException
|
||||
* @throws IOException
|
||||
* @throws CryptoException
|
||||
*/
|
||||
protected void performSync(Account account, Bundle extras, String authority,
|
||||
ContentProviderClient provider,
|
||||
SyncResult syncResult,
|
||||
String username, String password,
|
||||
String prefsPath,
|
||||
String serverURL, KeyBundle keyBundle)
|
||||
String serverURL,
|
||||
String syncKey)
|
||||
throws NoSuchAlgorithmException,
|
||||
SyncConfigurationException,
|
||||
IllegalArgumentException,
|
||||
AlreadySyncingException,
|
||||
IOException, ParseException,
|
||||
NonObjectJSONException {
|
||||
NonObjectJSONException, CryptoException {
|
||||
Logger.trace(LOG_TAG, "Performing sync.");
|
||||
|
||||
/**
|
||||
* Bug 769745: pickle Sync account parameters to JSON file. Un-pickle in
|
||||
* <code>SyncAccounts.syncAccountsExist</code>.
|
||||
*/
|
||||
try {
|
||||
// Constructor can throw on nulls, which should not happen -- but let's be safe.
|
||||
final SyncAccountParameters params = new SyncAccountParameters(mContext, mAccountManager,
|
||||
account.name, // Un-encoded, like "test@mozilla.com".
|
||||
syncKey,
|
||||
password,
|
||||
serverURL,
|
||||
null, // We'll re-fetch cluster URL; not great, but not harmful.
|
||||
getClientName(),
|
||||
getAccountGUID());
|
||||
|
||||
final boolean syncAutomatically = ContentResolver.getSyncAutomatically(account, authority);
|
||||
|
||||
AccountPickler.pickle(mContext, Constants.ACCOUNT_PICKLE_FILENAME, params, syncAutomatically);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
// TODO: default serverURL.
|
||||
final KeyBundle keyBundle = new KeyBundle(username, syncKey);
|
||||
GlobalSession globalSession = new GlobalSession(SyncConfiguration.DEFAULT_USER_API,
|
||||
serverURL, username, password, prefsPath,
|
||||
keyBundle, this, this.mContext, extras, this);
|
||||
|
@ -2,6 +2,7 @@ sync/AlreadySyncingException.java
|
||||
sync/CollectionKeys.java
|
||||
sync/CommandProcessor.java
|
||||
sync/CommandRunner.java
|
||||
sync/config/AccountPickler.java
|
||||
sync/CredentialsSource.java
|
||||
sync/crypto/CryptoException.java
|
||||
sync/crypto/CryptoInfo.java
|
||||
|
Loading…
Reference in New Issue
Block a user