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