|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.sync.receivers; |
|
6 |
|
7 import org.mozilla.gecko.sync.ExtendedJSONObject; |
|
8 import org.mozilla.gecko.background.common.GlobalConstants; |
|
9 import org.mozilla.gecko.background.common.log.Logger; |
|
10 import org.mozilla.gecko.sync.Sync11Configuration; |
|
11 import org.mozilla.gecko.sync.SyncConstants; |
|
12 import org.mozilla.gecko.sync.SyncConfiguration; |
|
13 import org.mozilla.gecko.sync.Utils; |
|
14 import org.mozilla.gecko.sync.config.AccountPickler; |
|
15 import org.mozilla.gecko.sync.config.ClientRecordTerminator; |
|
16 import org.mozilla.gecko.sync.net.BasicAuthHeaderProvider; |
|
17 import org.mozilla.gecko.sync.setup.Constants; |
|
18 import org.mozilla.gecko.sync.setup.SyncAccounts.SyncAccountParameters; |
|
19 |
|
20 import android.accounts.AccountManager; |
|
21 import android.app.IntentService; |
|
22 import android.content.Context; |
|
23 import android.content.Intent; |
|
24 import android.content.SharedPreferences; |
|
25 |
|
26 public class SyncAccountDeletedService extends IntentService { |
|
27 public static final String LOG_TAG = "SyncAccountDeletedService"; |
|
28 |
|
29 public SyncAccountDeletedService() { |
|
30 super(LOG_TAG); |
|
31 } |
|
32 |
|
33 @Override |
|
34 protected void onHandleIntent(Intent intent) { |
|
35 // Intent can, in theory, be null. Bug 1025937. |
|
36 if (intent == null) { |
|
37 Logger.debug(LOG_TAG, "Short-circuiting on null intent."); |
|
38 return; |
|
39 } |
|
40 |
|
41 final Context context = this; |
|
42 |
|
43 long intentVersion = intent.getLongExtra(Constants.JSON_KEY_VERSION, 0); |
|
44 long expectedVersion = SyncConstants.SYNC_ACCOUNT_DELETED_INTENT_VERSION; |
|
45 if (intentVersion != expectedVersion) { |
|
46 Logger.warn(LOG_TAG, "Intent malformed: version " + intentVersion + " given but version " + expectedVersion + "expected. " + |
|
47 "Not cleaning up after deleted Account."); |
|
48 return; |
|
49 } |
|
50 |
|
51 String accountName = intent.getStringExtra(Constants.JSON_KEY_ACCOUNT); // Android Account name, not Sync encoded account name. |
|
52 if (accountName == null) { |
|
53 Logger.warn(LOG_TAG, "Intent malformed: no account name given. Not cleaning up after deleted Account."); |
|
54 return; |
|
55 } |
|
56 |
|
57 // Delete the Account pickle. |
|
58 Logger.info(LOG_TAG, "Sync account named " + accountName + " being removed; " + |
|
59 "deleting saved pickle file '" + Constants.ACCOUNT_PICKLE_FILENAME + "'."); |
|
60 deletePickle(context); |
|
61 |
|
62 SyncAccountParameters params; |
|
63 try { |
|
64 String payload = intent.getStringExtra(Constants.JSON_KEY_PAYLOAD); |
|
65 if (payload == null) { |
|
66 Logger.warn(LOG_TAG, "Intent malformed: no payload given. Not deleting client record."); |
|
67 return; |
|
68 } |
|
69 ExtendedJSONObject o = ExtendedJSONObject.parseJSONObject(payload); |
|
70 params = new SyncAccountParameters(context, AccountManager.get(context), o); |
|
71 } catch (Exception e) { |
|
72 Logger.warn(LOG_TAG, "Got exception fetching account parameters from intent data; not deleting client record."); |
|
73 return; |
|
74 } |
|
75 |
|
76 // Bug 770785: delete the Account's client record. |
|
77 Logger.info(LOG_TAG, "Account named " + accountName + " being removed; " + |
|
78 "deleting client record from server."); |
|
79 deleteClientRecord(context, accountName, params.password, params.serverURL); |
|
80 } |
|
81 |
|
82 public static void deletePickle(final Context context) { |
|
83 try { |
|
84 AccountPickler.deletePickle(context, Constants.ACCOUNT_PICKLE_FILENAME); |
|
85 } catch (Exception e) { |
|
86 // This should never happen, but we really don't want to die in a background thread. |
|
87 Logger.warn(LOG_TAG, "Got exception deleting saved pickle file; ignoring.", e); |
|
88 } |
|
89 } |
|
90 |
|
91 public static void deleteClientRecord(final Context context, final String accountName, |
|
92 final String password, final String serverURL) { |
|
93 String encodedUsername; |
|
94 try { |
|
95 encodedUsername = Utils.usernameFromAccount(accountName); |
|
96 } catch (Exception e) { |
|
97 Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e); |
|
98 return; |
|
99 } |
|
100 |
|
101 if (accountName == null || encodedUsername == null || password == null || serverURL == null) { |
|
102 Logger.warn(LOG_TAG, "Account parameters were null; not deleting client record from server."); |
|
103 return; |
|
104 } |
|
105 |
|
106 // This is not exactly modular. We need to get some information about |
|
107 // the account, namely the current clusterURL and client GUID, and we |
|
108 // extract it by hand. We're not worried about the Account being |
|
109 // deleted out from under us since the prefs remain even after Account |
|
110 // deletion. |
|
111 final String product = GlobalConstants.BROWSER_INTENT_PACKAGE; |
|
112 final String profile = Constants.DEFAULT_PROFILE; |
|
113 final long version = SyncConfiguration.CURRENT_PREFS_VERSION; |
|
114 |
|
115 SharedPreferences prefs; |
|
116 try { |
|
117 prefs = Utils.getSharedPreferences(context, product, encodedUsername, serverURL, profile, version); |
|
118 } catch (Exception e) { |
|
119 Logger.warn(LOG_TAG, "Caught exception fetching preferences; not deleting client record from server.", e); |
|
120 return; |
|
121 } |
|
122 |
|
123 try { |
|
124 final String clientGUID = prefs.getString(SyncConfiguration.PREF_ACCOUNT_GUID, null); |
|
125 if (clientGUID == null) { |
|
126 Logger.warn(LOG_TAG, "Client GUID was null; not deleting client record from server."); |
|
127 return; |
|
128 } |
|
129 |
|
130 BasicAuthHeaderProvider authHeaderProvider = new BasicAuthHeaderProvider(encodedUsername, password); |
|
131 SyncConfiguration configuration = new Sync11Configuration(encodedUsername, authHeaderProvider, prefs); |
|
132 if (configuration.getClusterURL() == null) { |
|
133 Logger.warn(LOG_TAG, "Cluster URL was null; not deleting client record from server."); |
|
134 return; |
|
135 } |
|
136 |
|
137 try { |
|
138 ClientRecordTerminator.deleteClientRecord(configuration, clientGUID); |
|
139 } catch (Exception e) { |
|
140 // This should never happen, but we really don't want to die in a background thread. |
|
141 Logger.warn(LOG_TAG, "Got exception deleting client record from server; ignoring.", e); |
|
142 } |
|
143 } finally { |
|
144 // Finally, a good place to do this. |
|
145 prefs.edit().clear().commit(); |
|
146 } |
|
147 } |
|
148 } |