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; 18 19 import com.android.email.mail.Store; 20 21 import android.content.Context; 22 import android.content.SharedPreferences; 23 import android.net.Uri; 24 25 import java.io.Serializable; 26 import java.util.Arrays; 27 import java.util.UUID; 28 29 /** 30 * Account stores all of the settings for a single account defined by the user. It is able to save 31 * and delete itself given a Preferences to work with. Each account is defined by a UUID. 32 */ 33 public class Account implements Serializable { 34 public static final int DELETE_POLICY_NEVER = 0; 35 public static final int DELETE_POLICY_7DAYS = 1; 36 public static final int DELETE_POLICY_ON_DELETE = 2; 37 38 public static final int CHECK_INTERVAL_NEVER = -1; 39 public static final int CHECK_INTERVAL_PUSH = -2; 40 41 public static final int SYNC_WINDOW_USER = -1; 42 public static final int SYNC_WINDOW_1_DAY = 1; 43 public static final int SYNC_WINDOW_3_DAYS = 2; 44 public static final int SYNC_WINDOW_1_WEEK = 3; 45 public static final int SYNC_WINDOW_2_WEEKS = 4; 46 public static final int SYNC_WINDOW_1_MONTH = 5; 47 public static final int SYNC_WINDOW_ALL = 6; 48 49 /** 50 * This should never be used for persistance, only for marshalling. 51 * TODO: Remove serializable (VERY SLOW) and replace with Parcelable 52 */ 53 private static final long serialVersionUID = 1L; 54 55 // transient values - do not serialize 56 private transient Preferences mPreferences; 57 58 // serialized values 59 String mUuid; 60 String mStoreUri; 61 String mLocalStoreUri; 62 String mSenderUri; 63 String mDescription; 64 String mName; 65 String mEmail; 66 int mAutomaticCheckIntervalMinutes; 67 long mLastAutomaticCheckTime; 68 boolean mNotifyNewMail; 69 String mDraftsFolderName; 70 String mSentFolderName; 71 String mTrashFolderName; 72 String mOutboxFolderName; 73 int mAccountNumber; 74 boolean mVibrate; 75 String mRingtoneUri; 76 int mSyncWindow; 77 78 /** 79 * <pre> 80 * 0 Never 81 * 1 After 7 days 82 * 2 When I delete from inbox 83 * </pre> 84 */ 85 int mDeletePolicy; 86 87 /** 88 * All new fields should have named keys 89 */ 90 private final String KEY_SYNC_WINDOW = ".syncWindow"; 91 Account(Context context)92 public Account(Context context) { 93 // TODO Change local store path to something readable / recognizable 94 mUuid = UUID.randomUUID().toString(); 95 mLocalStoreUri = "local://localhost/" + context.getDatabasePath(mUuid + ".db"); 96 mAutomaticCheckIntervalMinutes = -1; 97 mAccountNumber = -1; 98 mNotifyNewMail = true; 99 mVibrate = false; 100 mRingtoneUri = "content://settings/system/notification_sound"; 101 mSyncWindow = SYNC_WINDOW_USER; // IMAP & POP3 102 } 103 Account(Preferences preferences, String uuid)104 Account(Preferences preferences, String uuid) { 105 this.mUuid = uuid; 106 refresh(preferences); 107 } 108 109 /** 110 * Refresh the account from the stored settings. 111 */ refresh(Preferences preferences)112 public void refresh(Preferences preferences) { 113 mPreferences = preferences; 114 115 mStoreUri = Utility.base64Decode(preferences.mSharedPreferences.getString(mUuid 116 + ".storeUri", null)); 117 mLocalStoreUri = preferences.mSharedPreferences.getString(mUuid + ".localStoreUri", null); 118 119 String senderText = preferences.mSharedPreferences.getString(mUuid + ".senderUri", null); 120 if (senderText == null) { 121 // Preference ".senderUri" was called ".transportUri" in earlier versions, so we'll 122 // do a simple upgrade here when necessary. 123 senderText = preferences.mSharedPreferences.getString(mUuid + ".transportUri", null); 124 } 125 mSenderUri = Utility.base64Decode(senderText); 126 127 mDescription = preferences.mSharedPreferences.getString(mUuid + ".description", null); 128 mName = preferences.mSharedPreferences.getString(mUuid + ".name", mName); 129 mEmail = preferences.mSharedPreferences.getString(mUuid + ".email", mEmail); 130 mAutomaticCheckIntervalMinutes = preferences.mSharedPreferences.getInt(mUuid 131 + ".automaticCheckIntervalMinutes", -1); 132 mLastAutomaticCheckTime = preferences.mSharedPreferences.getLong(mUuid 133 + ".lastAutomaticCheckTime", 0); 134 mNotifyNewMail = preferences.mSharedPreferences.getBoolean(mUuid + ".notifyNewMail", 135 false); 136 137 // delete policy was incorrectly set on earlier versions, so we'll upgrade it here. 138 // rule: if IMAP account and policy = 0 ("never"), change policy to 2 ("on delete") 139 mDeletePolicy = preferences.mSharedPreferences.getInt(mUuid + ".deletePolicy", 0); 140 if (mDeletePolicy == DELETE_POLICY_NEVER && 141 mStoreUri != null && mStoreUri.toString().startsWith(Store.STORE_SCHEME_IMAP)) { 142 mDeletePolicy = DELETE_POLICY_ON_DELETE; 143 } 144 145 mDraftsFolderName = preferences.mSharedPreferences.getString(mUuid + ".draftsFolderName", 146 "Drafts"); 147 mSentFolderName = preferences.mSharedPreferences.getString(mUuid + ".sentFolderName", 148 "Sent"); 149 mTrashFolderName = preferences.mSharedPreferences.getString(mUuid + ".trashFolderName", 150 "Trash"); 151 mOutboxFolderName = preferences.mSharedPreferences.getString(mUuid + ".outboxFolderName", 152 "Outbox"); 153 mAccountNumber = preferences.mSharedPreferences.getInt(mUuid + ".accountNumber", 0); 154 mVibrate = preferences.mSharedPreferences.getBoolean(mUuid + ".vibrate", false); 155 mRingtoneUri = preferences.mSharedPreferences.getString(mUuid + ".ringtone", 156 "content://settings/system/notification_sound"); 157 158 mSyncWindow = preferences.mSharedPreferences.getInt(mUuid + KEY_SYNC_WINDOW, 159 SYNC_WINDOW_USER); 160 } 161 getUuid()162 public String getUuid() { 163 return mUuid; 164 } 165 getStoreUri()166 public String getStoreUri() { 167 return mStoreUri; 168 } 169 setStoreUri(String storeUri)170 public void setStoreUri(String storeUri) { 171 this.mStoreUri = storeUri; 172 } 173 getSenderUri()174 public String getSenderUri() { 175 return mSenderUri; 176 } 177 setSenderUri(String senderUri)178 public void setSenderUri(String senderUri) { 179 this.mSenderUri = senderUri; 180 } 181 getDescription()182 public String getDescription() { 183 return mDescription; 184 } 185 setDescription(String description)186 public void setDescription(String description) { 187 this.mDescription = description; 188 } 189 getName()190 public String getName() { 191 return mName; 192 } 193 setName(String name)194 public void setName(String name) { 195 this.mName = name; 196 } 197 getEmail()198 public String getEmail() { 199 return mEmail; 200 } 201 setEmail(String email)202 public void setEmail(String email) { 203 this.mEmail = email; 204 } 205 isVibrate()206 public boolean isVibrate() { 207 return mVibrate; 208 } 209 setVibrate(boolean vibrate)210 public void setVibrate(boolean vibrate) { 211 mVibrate = vibrate; 212 } 213 getRingtone()214 public String getRingtone() { 215 return mRingtoneUri; 216 } 217 setRingtone(String ringtoneUri)218 public void setRingtone(String ringtoneUri) { 219 mRingtoneUri = ringtoneUri; 220 } 221 delete(Preferences preferences)222 public void delete(Preferences preferences) { 223 String[] uuids = preferences.mSharedPreferences.getString("accountUuids", "").split(","); 224 StringBuffer sb = new StringBuffer(); 225 for (int i = 0, length = uuids.length; i < length; i++) { 226 if (!uuids[i].equals(mUuid)) { 227 if (sb.length() > 0) { 228 sb.append(','); 229 } 230 sb.append(uuids[i]); 231 } 232 } 233 String accountUuids = sb.toString(); 234 SharedPreferences.Editor editor = preferences.mSharedPreferences.edit(); 235 editor.putString("accountUuids", accountUuids); 236 237 editor.remove(mUuid + ".storeUri"); 238 editor.remove(mUuid + ".localStoreUri"); 239 editor.remove(mUuid + ".senderUri"); 240 editor.remove(mUuid + ".description"); 241 editor.remove(mUuid + ".name"); 242 editor.remove(mUuid + ".email"); 243 editor.remove(mUuid + ".automaticCheckIntervalMinutes"); 244 editor.remove(mUuid + ".lastAutomaticCheckTime"); 245 editor.remove(mUuid + ".notifyNewMail"); 246 editor.remove(mUuid + ".deletePolicy"); 247 editor.remove(mUuid + ".draftsFolderName"); 248 editor.remove(mUuid + ".sentFolderName"); 249 editor.remove(mUuid + ".trashFolderName"); 250 editor.remove(mUuid + ".outboxFolderName"); 251 editor.remove(mUuid + ".accountNumber"); 252 editor.remove(mUuid + ".vibrate"); 253 editor.remove(mUuid + ".ringtone"); 254 editor.remove(mUuid + KEY_SYNC_WINDOW); 255 256 // also delete any deprecated fields 257 editor.remove(mUuid + ".transportUri"); 258 259 editor.commit(); 260 } 261 save(Preferences preferences)262 public void save(Preferences preferences) { 263 mPreferences = preferences; 264 265 if (!preferences.mSharedPreferences.getString("accountUuids", "").contains(mUuid)) { 266 /* 267 * When the account is first created we assign it a unique account number. The 268 * account number will be unique to that account for the lifetime of the account. 269 * So, we get all the existing account numbers, sort them ascending, loop through 270 * the list and check if the number is greater than 1 + the previous number. If so 271 * we use the previous number + 1 as the account number. This refills gaps. 272 * mAccountNumber starts as -1 on a newly created account. It must be -1 for this 273 * algorithm to work. 274 * 275 * I bet there is a much smarter way to do this. Anyone like to suggest it? 276 */ 277 Account[] accounts = preferences.getAccounts(); 278 int[] accountNumbers = new int[accounts.length]; 279 for (int i = 0; i < accounts.length; i++) { 280 accountNumbers[i] = accounts[i].getAccountNumber(); 281 } 282 Arrays.sort(accountNumbers); 283 for (int accountNumber : accountNumbers) { 284 if (accountNumber > mAccountNumber + 1) { 285 break; 286 } 287 mAccountNumber = accountNumber; 288 } 289 mAccountNumber++; 290 291 String accountUuids = preferences.mSharedPreferences.getString("accountUuids", ""); 292 accountUuids += (accountUuids.length() != 0 ? "," : "") + mUuid; 293 SharedPreferences.Editor editor = preferences.mSharedPreferences.edit(); 294 editor.putString("accountUuids", accountUuids); 295 editor.commit(); 296 } 297 298 SharedPreferences.Editor editor = preferences.mSharedPreferences.edit(); 299 300 editor.putString(mUuid + ".storeUri", Utility.base64Encode(mStoreUri)); 301 editor.putString(mUuid + ".localStoreUri", mLocalStoreUri); 302 editor.putString(mUuid + ".senderUri", Utility.base64Encode(mSenderUri)); 303 editor.putString(mUuid + ".description", mDescription); 304 editor.putString(mUuid + ".name", mName); 305 editor.putString(mUuid + ".email", mEmail); 306 editor.putInt(mUuid + ".automaticCheckIntervalMinutes", mAutomaticCheckIntervalMinutes); 307 editor.putLong(mUuid + ".lastAutomaticCheckTime", mLastAutomaticCheckTime); 308 editor.putBoolean(mUuid + ".notifyNewMail", mNotifyNewMail); 309 editor.putInt(mUuid + ".deletePolicy", mDeletePolicy); 310 editor.putString(mUuid + ".draftsFolderName", mDraftsFolderName); 311 editor.putString(mUuid + ".sentFolderName", mSentFolderName); 312 editor.putString(mUuid + ".trashFolderName", mTrashFolderName); 313 editor.putString(mUuid + ".outboxFolderName", mOutboxFolderName); 314 editor.putInt(mUuid + ".accountNumber", mAccountNumber); 315 editor.putBoolean(mUuid + ".vibrate", mVibrate); 316 editor.putString(mUuid + ".ringtone", mRingtoneUri); 317 editor.putInt(mUuid + KEY_SYNC_WINDOW, mSyncWindow); 318 319 // The following fields are *not* written because they need to be more fine-grained 320 // and not risk rewriting with old data. 321 // editor.putString(mUuid + PREF_TAG_STORE_PERSISTENT, mStorePersistent); 322 323 // also delete any deprecated fields 324 editor.remove(mUuid + ".transportUri"); 325 326 editor.commit(); 327 } 328 329 @Override toString()330 public String toString() { 331 return mDescription; 332 } 333 getContentUri()334 public Uri getContentUri() { 335 return Uri.parse("content://accounts/" + getUuid()); 336 } 337 getLocalStoreUri()338 public String getLocalStoreUri() { 339 return mLocalStoreUri; 340 } 341 setLocalStoreUri(String localStoreUri)342 public void setLocalStoreUri(String localStoreUri) { 343 this.mLocalStoreUri = localStoreUri; 344 } 345 346 /** 347 * Returns -1 for never. 348 */ getAutomaticCheckIntervalMinutes()349 public int getAutomaticCheckIntervalMinutes() { 350 return mAutomaticCheckIntervalMinutes; 351 } 352 353 /** 354 * @param automaticCheckIntervalMinutes or -1 for never. 355 */ setAutomaticCheckIntervalMinutes(int automaticCheckIntervalMinutes)356 public void setAutomaticCheckIntervalMinutes(int automaticCheckIntervalMinutes) { 357 this.mAutomaticCheckIntervalMinutes = automaticCheckIntervalMinutes; 358 } 359 getLastAutomaticCheckTime()360 public long getLastAutomaticCheckTime() { 361 return mLastAutomaticCheckTime; 362 } 363 setLastAutomaticCheckTime(long lastAutomaticCheckTime)364 public void setLastAutomaticCheckTime(long lastAutomaticCheckTime) { 365 this.mLastAutomaticCheckTime = lastAutomaticCheckTime; 366 } 367 isNotifyNewMail()368 public boolean isNotifyNewMail() { 369 return mNotifyNewMail; 370 } 371 setNotifyNewMail(boolean notifyNewMail)372 public void setNotifyNewMail(boolean notifyNewMail) { 373 this.mNotifyNewMail = notifyNewMail; 374 } 375 getDeletePolicy()376 public int getDeletePolicy() { 377 return mDeletePolicy; 378 } 379 setDeletePolicy(int deletePolicy)380 public void setDeletePolicy(int deletePolicy) { 381 this.mDeletePolicy = deletePolicy; 382 } 383 getDraftsFolderName()384 public String getDraftsFolderName() { 385 return mDraftsFolderName; 386 } 387 setDraftsFolderName(String draftsFolderName)388 public void setDraftsFolderName(String draftsFolderName) { 389 mDraftsFolderName = draftsFolderName; 390 } 391 getSentFolderName()392 public String getSentFolderName() { 393 return mSentFolderName; 394 } 395 setSentFolderName(String sentFolderName)396 public void setSentFolderName(String sentFolderName) { 397 mSentFolderName = sentFolderName; 398 } 399 getTrashFolderName()400 public String getTrashFolderName() { 401 return mTrashFolderName; 402 } 403 setTrashFolderName(String trashFolderName)404 public void setTrashFolderName(String trashFolderName) { 405 mTrashFolderName = trashFolderName; 406 } 407 getOutboxFolderName()408 public String getOutboxFolderName() { 409 return mOutboxFolderName; 410 } 411 setOutboxFolderName(String outboxFolderName)412 public void setOutboxFolderName(String outboxFolderName) { 413 mOutboxFolderName = outboxFolderName; 414 } 415 getAccountNumber()416 public int getAccountNumber() { 417 return mAccountNumber; 418 } 419 getSyncWindow()420 public int getSyncWindow() { 421 return mSyncWindow; 422 } 423 setSyncWindow(int window)424 public void setSyncWindow(int window) { 425 mSyncWindow = window; 426 } 427 428 @Override equals(Object o)429 public boolean equals(Object o) { 430 if (o instanceof Account) { 431 return ((Account)o).mUuid.equals(mUuid); 432 } 433 return super.equals(o); 434 } 435 } 436