mobile/android/base/sync/receivers/SyncAccountDeletedService.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/sync/receivers/SyncAccountDeletedService.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,148 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +package org.mozilla.gecko.sync.receivers;
     1.9 +
    1.10 +import org.mozilla.gecko.sync.ExtendedJSONObject;
    1.11 +import org.mozilla.gecko.background.common.GlobalConstants;
    1.12 +import org.mozilla.gecko.background.common.log.Logger;
    1.13 +import org.mozilla.gecko.sync.Sync11Configuration;
    1.14 +import org.mozilla.gecko.sync.SyncConstants;
    1.15 +import org.mozilla.gecko.sync.SyncConfiguration;
    1.16 +import org.mozilla.gecko.sync.Utils;
    1.17 +import org.mozilla.gecko.sync.config.AccountPickler;
    1.18 +import org.mozilla.gecko.sync.config.ClientRecordTerminator;
    1.19 +import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider;
    1.20 +import org.mozilla.gecko.sync.setup.Constants;
    1.21 +import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters;
    1.22 +
    1.23 +import android.accounts.AccountManager;
    1.24 +import android.app.IntentService;
    1.25 +import android.content.Context;
    1.26 +import android.content.Intent;
    1.27 +import android.content.SharedPreferences;
    1.28 +
    1.29 +public class SyncAccountDeletedService extends IntentService {
    1.30 +  public static final String LOG_TAG = "SyncAccountDeletedService";
    1.31 +
    1.32 +  public SyncAccountDeletedService() {
    1.33 +    super(LOG_TAG);
    1.34 +  }
    1.35 +
    1.36 +  @Override
    1.37 +  protected void onHandleIntent(Intent intent) {
    1.38 +    // Intent can, in theory, be null. Bug 1025937.
    1.39 +    if (intent == null) {
    1.40 +      Logger.debug(LOG_TAG, "Short-circuiting on null intent.");
    1.41 +      return;
    1.42 +    }
    1.43 +
    1.44 +    final Context context = this;
    1.45 +
    1.46 +    long intentVersion = intent.getLongExtra(Constants.JSON_KEY_VERSION, 0);
    1.47 +    long expectedVersion = SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION;
    1.48 +    if (intentVersion != expectedVersion) {
    1.49 +      Logger.warn(LOG_TAG, "Intent malformed: version " + intentVersion + " given but version " + expectedVersion + "expected. " +
    1.50 +          "Not cleaning up after deleted Account.");
    1.51 +      return;
    1.52 +    }
    1.53 +
    1.54 +    String accountName = intent.getStringExtra(Constants.JSON_KEY_ACCOUNT); // Android Account name, not Sync encoded account name.
    1.55 +    if (accountName == null) {
    1.56 +      Logger.warn(LOG_TAG, "Intent malformed: no account name given. Not cleaning up after deleted Account.");
    1.57 +      return;
    1.58 +    }
    1.59 +
    1.60 +    // Delete the Account pickle.
    1.61 +    Logger.info(LOG_TAG, "Sync account named " + accountName + " being removed; " +
    1.62 +        "deleting saved pickle file '" + Constants.ACCOUNT_PICKLE_FILENAME + "'.");
    1.63 +    deletePickle(context);
    1.64 +
    1.65 +    SyncAccountParameters params;
    1.66 +    try {
    1.67 +      String payload = intent.getStringExtra(Constants.JSON_KEY_PAYLOAD);
    1.68 +      if (payload == null) {
    1.69 +        Logger.warn(LOG_TAG, "Intent malformed: no payload given. Not deleting client record.");
    1.70 +        return;
    1.71 +      }
    1.72 +      ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(payload);
    1.73 +      params = new SyncAccountParameters(context, AccountManager.get(context), o);
    1.74 +    } catch (Exception e) {
    1.75 +      Logger.warn(LOG_TAG, "Got exception fetching account parameters from intent data; not deleting client record.");
    1.76 +      return;
    1.77 +    }
    1.78 +
    1.79 +    // Bug 770785: delete the Account's client record.
    1.80 +    Logger.info(LOG_TAG, "Account named " + accountName + " being removed; " +
    1.81 +        "deleting client record from server.");
    1.82 +    deleteClientRecord(context, accountName, params.password, params.serverURL);
    1.83 +  }
    1.84 +
    1.85 +  public static void deletePickle(final Context context) {
    1.86 +    try {
    1.87 +      AccountPickler.deletePickle(context, Constants.ACCOUNT_PICKLE_FILENAME);
    1.88 +    } catch (Exception e) {
    1.89 +      // This should never happen, but we really don't want to die in a background thread.
    1.90 +      Logger.warn(LOG_TAG, "Got exception deleting saved pickle file; ignoring.", e);
    1.91 +    }
    1.92 +  }
    1.93 +
    1.94 +  public static void deleteClientRecord(final Context context, final String accountName,
    1.95 +      final String password, final String serverURL) {
    1.96 +    String encodedUsername;
    1.97 +    try {
    1.98 +      encodedUsername = Utils.usernameFromAccount(accountName);
    1.99 +    } catch (Exception e) {
   1.100 +      Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
   1.101 +      return;
   1.102 +    }
   1.103 +
   1.104 +    if (accountName == null || encodedUsername == null || password == null || serverURL == null) {
   1.105 +      Logger.warn(LOG_TAG, "Account parameters were null; not deleting client record from server.");
   1.106 +      return;
   1.107 +    }
   1.108 +
   1.109 +    // This is not exactly modular. We need to get some information about
   1.110 +    // the account, namely the current clusterURL and client GUID, and we
   1.111 +    // extract it by hand. We're not worried about the Account being
   1.112 +    // deleted out from under us since the prefs remain even after Account
   1.113 +    // deletion.
   1.114 +    final String product = GlobalConstants.BROWSER_INTENT_PACKAGE;
   1.115 +    final String profile = Constants.DEFAULT_PROFILE;
   1.116 +    final long version = SyncConfiguration.CURRENT_PREFS_VERSION;
   1.117 +
   1.118 +    SharedPreferences prefs;
   1.119 +    try {
   1.120 +      prefs = Utils.getSharedPreferences(context, product, encodedUsername, serverURL, profile, version);
   1.121 +    } catch (Exception e) {
   1.122 +      Logger.warn(LOG_TAG, "Caught exception fetching preferences; not deleting client record from server.", e);
   1.123 +      return;
   1.124 +    }
   1.125 +
   1.126 +    try {
   1.127 +      final String clientGUID = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null);
   1.128 +      if (clientGUID == null) {
   1.129 +        Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server.");
   1.130 +        return;
   1.131 +      }
   1.132 +
   1.133 +      BasicAuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(encodedUsername, password);
   1.134 +      SyncConfiguration configuration = new Sync11Configuration(encodedUsername, authHeaderProvider, prefs);
   1.135 +      if (configuration.getClusterURL() == null) {
   1.136 +        Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server.");
   1.137 +        return;
   1.138 +      }
   1.139 +
   1.140 +      try {
   1.141 +        ClientRecordTerminator.deleteClientRecord(configuration, clientGUID);
   1.142 +      } catch (Exception e) {
   1.143 +        // This should never happen, but we really don't want to die in a background thread.
   1.144 +        Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e);
   1.145 +      }
   1.146 +    } finally {
   1.147 +      // Finally, a good place to do this.
   1.148 +      prefs.edit().clear().commit();
   1.149 +    }
   1.150 +  }
   1.151 +}

mercurial