• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.email.activity.setup;
18 
19 import com.android.email.Email;
20 import com.android.email.R;
21 import com.android.email.mail.MessagingException;
22 import com.android.email.mail.Sender;
23 import com.android.email.mail.Store;
24 import com.android.email.provider.EmailContent.Account;
25 import com.android.email.provider.EmailContent.AccountColumns;
26 import com.android.email.provider.EmailContent.HostAuth;
27 import com.android.exchange.Eas;
28 
29 import android.app.Activity;
30 import android.content.ContentResolver;
31 import android.content.Intent;
32 import android.content.SharedPreferences;
33 import android.database.Cursor;
34 import android.os.Bundle;
35 import android.preference.CheckBoxPreference;
36 import android.preference.EditTextPreference;
37 import android.preference.ListPreference;
38 import android.preference.Preference;
39 import android.preference.PreferenceActivity;
40 import android.preference.PreferenceCategory;
41 import android.preference.RingtonePreference;
42 import android.provider.ContactsContract;
43 import android.util.Log;
44 import android.view.KeyEvent;
45 
46 public class AccountSettings extends PreferenceActivity {
47     private static final String PREFERENCE_TOP_CATEGORY = "account_settings";
48     private static final String PREFERENCE_DESCRIPTION = "account_description";
49     private static final String PREFERENCE_NAME = "account_name";
50     private static final String PREFERENCE_FREQUENCY = "account_check_frequency";
51     private static final String PREFERENCE_DEFAULT = "account_default";
52     private static final String PREFERENCE_NOTIFY = "account_notify";
53     private static final String PREFERENCE_VIBRATE = "account_vibrate";
54     private static final String PREFERENCE_RINGTONE = "account_ringtone";
55     private static final String PREFERENCE_SERVER_CATERGORY = "account_servers";
56     private static final String PREFERENCE_INCOMING = "incoming";
57     private static final String PREFERENCE_OUTGOING = "outgoing";
58     private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts";
59 
60     // NOTE: This string must match the one in res/xml/account_preferences.xml
61     public static final String ACTION_ACCOUNT_MANAGER_ENTRY =
62         "com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY";
63     // NOTE: This constant should eventually be defined in android.accounts.Constants, but for
64     // now we define it here
65     private static final String ACCOUNT_MANAGER_EXTRA_ACCOUNT = "account";
66     private static final String EXTRA_ACCOUNT_ID = "account_id";
67 
68     private long mAccountId = -1;
69     private Account mAccount;
70     private boolean mAccountDirty;
71 
72     private EditTextPreference mAccountDescription;
73     private EditTextPreference mAccountName;
74     private ListPreference mCheckFrequency;
75     private ListPreference mSyncWindow;
76     private CheckBoxPreference mAccountDefault;
77     private CheckBoxPreference mAccountNotify;
78     private CheckBoxPreference mAccountVibrate;
79     private RingtonePreference mAccountRingtone;
80     private CheckBoxPreference mSyncContacts;
81 
82     /**
83      * Display (and edit) settings for a specific account
84      */
actionSettings(Activity fromActivity, long accountId)85     public static void actionSettings(Activity fromActivity, long accountId) {
86         Intent i = new Intent(fromActivity, AccountSettings.class);
87         i.putExtra(EXTRA_ACCOUNT_ID, accountId);
88         fromActivity.startActivity(i);
89     }
90 
91     @Override
onCreate(Bundle savedInstanceState)92     public void onCreate(Bundle savedInstanceState) {
93         super.onCreate(savedInstanceState);
94 
95         Intent i = getIntent();
96         if (ACTION_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) {
97             // This case occurs if we're changing account settings from Settings -> Accounts
98             setAccountIdFromAccountManagerIntent();
99         } else {
100             // Otherwise, we're called from within the Email app and look for our extra
101             mAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1);
102         }
103 
104         // If there's no accountId, we're done
105         if (mAccountId == -1) {
106             finish();
107             return;
108         }
109 
110         mAccount = Account.restoreAccountWithId(this, mAccountId);
111         // Similarly, if the account has been deleted
112         if (mAccount == null) {
113             finish();
114             return;
115         }
116         mAccount.mHostAuthRecv = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeyRecv);
117         mAccount.mHostAuthSend = HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeySend);
118         // Or if HostAuth's have been deleted
119         if (mAccount.mHostAuthRecv == null || mAccount.mHostAuthSend == null) {
120             finish();
121             return;
122         }
123         mAccountDirty = false;
124 
125         addPreferencesFromResource(R.xml.account_settings_preferences);
126 
127         PreferenceCategory topCategory = (PreferenceCategory) findPreference(PREFERENCE_TOP_CATEGORY);
128         topCategory.setTitle(getString(R.string.account_settings_title_fmt));
129 
130         mAccountDescription = (EditTextPreference) findPreference(PREFERENCE_DESCRIPTION);
131         mAccountDescription.setSummary(mAccount.getDisplayName());
132         mAccountDescription.setText(mAccount.getDisplayName());
133         mAccountDescription.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
134             public boolean onPreferenceChange(Preference preference, Object newValue) {
135                 final String summary = newValue.toString();
136                 mAccountDescription.setSummary(summary);
137                 mAccountDescription.setText(summary);
138                 return false;
139             }
140         });
141 
142         mAccountName = (EditTextPreference) findPreference(PREFERENCE_NAME);
143         mAccountName.setSummary(mAccount.getSenderName());
144         mAccountName.setText(mAccount.getSenderName());
145         mAccountName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
146             public boolean onPreferenceChange(Preference preference, Object newValue) {
147                 final String summary = newValue.toString();
148                 mAccountName.setSummary(summary);
149                 mAccountName.setText(summary);
150                 return false;
151             }
152         });
153 
154         mCheckFrequency = (ListPreference) findPreference(PREFERENCE_FREQUENCY);
155 
156         // Before setting value, we may need to adjust the lists
157         Store.StoreInfo info = Store.StoreInfo.getStoreInfo(mAccount.getStoreUri(this), this);
158         if (info.mPushSupported) {
159             mCheckFrequency.setEntries(R.array.account_settings_check_frequency_entries_push);
160             mCheckFrequency.setEntryValues(R.array.account_settings_check_frequency_values_push);
161         }
162 
163         mCheckFrequency.setValue(String.valueOf(mAccount.getSyncInterval()));
164         mCheckFrequency.setSummary(mCheckFrequency.getEntry());
165         mCheckFrequency.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
166             public boolean onPreferenceChange(Preference preference, Object newValue) {
167                 final String summary = newValue.toString();
168                 int index = mCheckFrequency.findIndexOfValue(summary);
169                 mCheckFrequency.setSummary(mCheckFrequency.getEntries()[index]);
170                 mCheckFrequency.setValue(summary);
171                 return false;
172             }
173         });
174 
175         // Add check window preference
176         mSyncWindow = null;
177         if (info.mVisibleLimitDefault == -1) {
178             mSyncWindow = new ListPreference(this);
179             mSyncWindow.setTitle(R.string.account_setup_options_mail_window_label);
180             mSyncWindow.setEntries(R.array.account_settings_mail_window_entries);
181             mSyncWindow.setEntryValues(R.array.account_settings_mail_window_values);
182             mSyncWindow.setValue(String.valueOf(mAccount.getSyncLookback()));
183             mSyncWindow.setSummary(mSyncWindow.getEntry());
184             mSyncWindow.setOrder(4);
185             mSyncWindow.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
186                 public boolean onPreferenceChange(Preference preference, Object newValue) {
187                     final String summary = newValue.toString();
188                     int index = mSyncWindow.findIndexOfValue(summary);
189                     mSyncWindow.setSummary(mSyncWindow.getEntries()[index]);
190                     mSyncWindow.setValue(summary);
191                     return false;
192                 }
193             });
194             topCategory.addPreference(mSyncWindow);
195         }
196 
197         mAccountDefault = (CheckBoxPreference) findPreference(PREFERENCE_DEFAULT);
198         mAccountDefault.setChecked(mAccount.mId == Account.getDefaultAccountId(this));
199 
200         mAccountNotify = (CheckBoxPreference) findPreference(PREFERENCE_NOTIFY);
201         mAccountNotify.setChecked(0 != (mAccount.getFlags() & Account.FLAGS_NOTIFY_NEW_MAIL));
202 
203         mAccountRingtone = (RingtonePreference) findPreference(PREFERENCE_RINGTONE);
204 
205         // XXX: The following two lines act as a workaround for the RingtonePreference
206         //      which does not let us set/get the value programmatically
207         SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
208         prefs.edit().putString(PREFERENCE_RINGTONE, mAccount.getRingtone()).commit();
209 
210         mAccountVibrate = (CheckBoxPreference) findPreference(PREFERENCE_VIBRATE);
211         mAccountVibrate.setChecked(0 !=
212             (mAccount.getFlags() & Account.FLAGS_VIBRATE));
213 
214         findPreference(PREFERENCE_INCOMING).setOnPreferenceClickListener(
215                 new Preference.OnPreferenceClickListener() {
216                     public boolean onPreferenceClick(Preference preference) {
217                         onIncomingSettings();
218                         return true;
219                     }
220                 });
221 
222         // Hide the outgoing account setup link if it's not activated
223         Preference prefOutgoing = findPreference(PREFERENCE_OUTGOING);
224         boolean showOutgoing = true;
225         try {
226             Sender sender = Sender.getInstance(getApplication(), mAccount.getSenderUri(this));
227             if (sender != null) {
228                 Class<? extends android.app.Activity> setting = sender.getSettingActivityClass();
229                 showOutgoing = (setting != null);
230             }
231         } catch (MessagingException me) {
232             // just leave showOutgoing as true - bias towards showing it, so user can fix it
233         }
234         if (showOutgoing) {
235             prefOutgoing.setOnPreferenceClickListener(
236                     new Preference.OnPreferenceClickListener() {
237                         public boolean onPreferenceClick(Preference preference) {
238                             onOutgoingSettings();
239                             return true;
240                         }
241                     });
242         } else {
243             PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
244                     PREFERENCE_SERVER_CATERGORY);
245             serverCategory.removePreference(prefOutgoing);
246         }
247 
248         mSyncContacts = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CONTACTS);
249         if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) {
250             android.accounts.Account acct =
251                 new android.accounts.Account(mAccount.mEmailAddress, Eas.ACCOUNT_MANAGER_TYPE);
252             mSyncContacts.setChecked(ContentResolver
253                     .getSyncAutomatically(acct, ContactsContract.AUTHORITY));
254         } else {
255             PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
256                     PREFERENCE_SERVER_CATERGORY);
257             serverCategory.removePreference(mSyncContacts);
258         }
259     }
260 
setAccountIdFromAccountManagerIntent()261     private void setAccountIdFromAccountManagerIntent() {
262         // First, get the AccountManager account that we've been ask to handle
263         android.accounts.Account acct =
264             (android.accounts.Account)getIntent()
265             .getParcelableExtra(ACCOUNT_MANAGER_EXTRA_ACCOUNT);
266         // Find a HostAuth using eas and whose login is klthe name of the AccountManager account
267         Cursor c = getContentResolver().query(Account.CONTENT_URI,
268                 new String[] {AccountColumns.ID}, AccountColumns.EMAIL_ADDRESS + "=?",
269                 new String[] {acct.name}, null);
270         try {
271             if (c.moveToFirst()) {
272                 mAccountId = c.getLong(0);
273             }
274         } finally {
275             c.close();
276         }
277     }
278 
279     @Override
onResume()280     public void onResume() {
281         super.onResume();
282         if (mAccountDirty) {
283             // if we are coming back from editing incoming or outgoing settings,
284             // we need to refresh them here so we don't accidentally overwrite the
285             // old values we're still holding here
286             mAccount.mHostAuthRecv =
287                 HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeyRecv);
288             mAccount.mHostAuthSend =
289                 HostAuth.restoreHostAuthWithId(this, mAccount.mHostAuthKeySend);
290             // Because "delete policy" UI is on edit incoming settings, we have
291             // to refresh that as well.
292             Account refreshedAccount = Account.restoreAccountWithId(this, mAccount.mId);
293             if (refreshedAccount == null || mAccount.mHostAuthRecv == null
294                     || mAccount.mHostAuthSend == null) {
295                 finish();
296                 return;
297             }
298             mAccount.setDeletePolicy(refreshedAccount.getDeletePolicy());
299             mAccountDirty = false;
300         }
301     }
302 
saveSettings()303     private void saveSettings() {
304         int newFlags = mAccount.getFlags() &
305                 ~(Account.FLAGS_NOTIFY_NEW_MAIL | Account.FLAGS_VIBRATE);
306 
307         mAccount.setDefaultAccount(mAccountDefault.isChecked());
308         mAccount.setDisplayName(mAccountDescription.getText());
309         mAccount.setSenderName(mAccountName.getText());
310         newFlags |= mAccountNotify.isChecked() ? Account.FLAGS_NOTIFY_NEW_MAIL : 0;
311         mAccount.setSyncInterval(Integer.parseInt(mCheckFrequency.getValue()));
312         if (mSyncWindow != null) {
313             mAccount.setSyncLookback(Integer.parseInt(mSyncWindow.getValue()));
314         }
315         newFlags |= mAccountVibrate.isChecked() ? Account.FLAGS_VIBRATE : 0;
316         SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
317         mAccount.setRingtone(prefs.getString(PREFERENCE_RINGTONE, null));
318         mAccount.setFlags(newFlags);
319 
320         if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) {
321             android.accounts.Account acct =
322                 new android.accounts.Account(mAccount.mEmailAddress, Eas.ACCOUNT_MANAGER_TYPE);
323             ContentResolver.setSyncAutomatically(acct, ContactsContract.AUTHORITY,
324                     mSyncContacts.isChecked());
325 
326         }
327         AccountSettingsUtils.commitSettings(this, mAccount);
328         Email.setServicesEnabled(this);
329     }
330 
331     @Override
onKeyDown(int keyCode, KeyEvent event)332     public boolean onKeyDown(int keyCode, KeyEvent event) {
333         if (keyCode == KeyEvent.KEYCODE_BACK) {
334             saveSettings();
335         }
336         return super.onKeyDown(keyCode, event);
337     }
338 
onIncomingSettings()339     private void onIncomingSettings() {
340         try {
341             Store store = Store.getInstance(mAccount.getStoreUri(this), getApplication(), null);
342             if (store != null) {
343                 Class<? extends android.app.Activity> setting = store.getSettingActivityClass();
344                 if (setting != null) {
345                     java.lang.reflect.Method m = setting.getMethod("actionEditIncomingSettings",
346                             android.app.Activity.class, Account.class);
347                     m.invoke(null, this, mAccount);
348                     mAccountDirty = true;
349                 }
350             }
351         } catch (Exception e) {
352             Log.d(Email.LOG_TAG, "Error while trying to invoke store settings.", e);
353         }
354     }
355 
onOutgoingSettings()356     private void onOutgoingSettings() {
357         try {
358             Sender sender = Sender.getInstance(getApplication(), mAccount.getSenderUri(this));
359             if (sender != null) {
360                 Class<? extends android.app.Activity> setting = sender.getSettingActivityClass();
361                 if (setting != null) {
362                     java.lang.reflect.Method m = setting.getMethod("actionEditOutgoingSettings",
363                             android.app.Activity.class, Account.class);
364                     m.invoke(null, this, mAccount);
365                     mAccountDirty = true;
366                 }
367             }
368         } catch (Exception e) {
369             Log.d(Email.LOG_TAG, "Error while trying to invoke sender settings.", e);
370         }
371     }
372 }
373