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