/* 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.receivers; import org.mozilla.gecko.sync.ExtendedJSONObject; import org.mozilla.gecko.sync.GlobalConstants; import org.mozilla.gecko.sync.SyncConstants; 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.config.ClientRecordTerminator; import org.mozilla.gecko.sync.setup.Constants; import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters; import android.accounts.AccountManager; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; public class SyncAccountDeletedService extends IntentService { public static final String LOG_TAG = "SyncAccountDeletedService"; public SyncAccountDeletedService() { super(LOG_TAG); } @Override protected void onHandleIntent(Intent intent) { final Context context = this; long intentVersion = intent.getLongExtra(Constants.JSON_KEY_VERSION, 0); long expectedVersion = SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION; if (intentVersion != expectedVersion) { Logger.warn(LOG_TAG, "Intent malformed: version " + intentVersion + " given but version " + expectedVersion + "expected. " + "Not cleaning up after deleted Account."); return; } String accountName = intent.getStringExtra(Constants.JSON_KEY_ACCOUNT); // Android Account name, not Sync encoded account name. if (accountName == null) { Logger.warn(LOG_TAG, "Intent malformed: no account name given. Not cleaning up after deleted Account."); return; } // Delete the Account pickle. Logger.info(LOG_TAG, "Sync account named " + accountName + " being removed; " + "deleting saved pickle file '" + Constants.ACCOUNT_PICKLE_FILENAME + "'."); deletePickle(context); SyncAccountParameters params; try { String payload = intent.getStringExtra(Constants.JSON_KEY_PAYLOAD); if (payload == null) { Logger.warn(LOG_TAG, "Intent malformed: no payload given. Not deleting client record."); return; } ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(payload); params = new SyncAccountParameters(context, AccountManager.get(context), o); } catch (Exception e) { Logger.warn(LOG_TAG, "Got exception fetching account parameters from intent data; not deleting client record."); return; } // Bug 770785: delete the Account's client record. Logger.info(LOG_TAG, "Account named " + accountName + " being removed; " + "deleting client record from server."); deleteClientRecord(context, accountName, params.password, params.serverURL); } public static void deletePickle(final Context context) { try { AccountPickler.deletePickle(context, Constants.ACCOUNT_PICKLE_FILENAME); } catch (Exception e) { // This should never happen, but we really don't want to die in a background thread. Logger.warn(LOG_TAG, "Got exception deleting saved pickle file; ignoring.", e); } } public static void deleteClientRecord(final Context context, final String accountName, final String password, final String serverURL) { String encodedUsername; try { encodedUsername = Utils.usernameFromAccount(accountName); } catch (Exception e) { Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e); return; } if (accountName == null || encodedUsername == null || password == null || serverURL == null) { Logger.warn(LOG_TAG, "Account parameters were null; not deleting client record from server."); return; } // This is not exactly modular. We need to get some information about // the account, namely the current clusterURL and client GUID, and we // extract it by hand. We're not worried about the Account being // deleted out from under us since the prefs remain even after Account // deletion. final String product = GlobalConstants.BROWSER_INTENT_PACKAGE; final String profile = Constants.DEFAULT_PROFILE; final long version = SyncConfiguration.CURRENT_PREFS_VERSION; SharedPreferences prefs; try { prefs = Utils.getSharedPreferences(context, product, encodedUsername, serverURL, profile, version); } catch (Exception e) { Logger.warn(LOG_TAG, "Caught exception fetching preferences; not deleting client record from server.", e); return; } final String clientGuid = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null); final String clusterURL = prefs.getString(SyncConfiguration.PREF_CLUSTER_URL, null); // Finally, a good place to do this. prefs.edit().clear().commit(); if (clientGuid == null) { Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server."); return; } if (clusterURL == null) { Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server."); return; } try { ClientRecordTerminator.deleteClientRecord(encodedUsername, password, clusterURL, clientGuid); } catch (Exception e) { // This should never happen, but we really don't want to die in a background thread. Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e); } } }