Home | History | Annotate | Download | only in contacts
      1 /*
      2  * Copyright (C) 2009 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.providers.contacts;
     18 
     19 import android.accounts.Account;
     20 import android.content.Context;
     21 import android.database.sqlite.SQLiteDatabase;
     22 import android.util.Log;
     23 
     24 import junit.framework.Assert;
     25 
     26 import java.util.Locale;
     27 
     28 /**
     29  * A version of {@link ContactsProvider2} class that performs aggregation
     30  * synchronously and wipes all data at construction time.
     31  */
     32 public class SynchronousContactsProvider2 extends ContactsProvider2 {
     33     public static final String READ_ONLY_ACCOUNT_TYPE = "ro";
     34 
     35     private static Boolean sDataWiped = false;
     36     private static ContactsDatabaseHelper sDbHelper;
     37     private boolean mDataWipeEnabled = true;
     38     private Account mAccount;
     39     private boolean mNetworkNotified;
     40     private boolean mIsPhone = true;
     41     private boolean mIsVoiceCapable = true;
     42 
     43     @Override
     44     protected ContactsDatabaseHelper getDatabaseHelper(final Context context) {
     45         if (sDbHelper == null) {
     46             sDbHelper = ContactsDatabaseHelper.getNewInstanceForTest(context);
     47         }
     48         return sDbHelper;
     49     }
     50 
     51     @Override
     52     public ProfileProvider newProfileProvider() {
     53         return new SynchronousProfileProvider(this);
     54     }
     55 
     56     public void setDataWipeEnabled(boolean flag) {
     57         mDataWipeEnabled = flag;
     58     }
     59 
     60     @Override
     61     public void onBegin() {
     62         super.onBegin();
     63         mNetworkNotified = false;
     64     }
     65 
     66     @Override
     67     protected void notifyChange(boolean syncToNetwork) {
     68         mNetworkNotified |= syncToNetwork;
     69     }
     70 
     71     public boolean isNetworkNotified() {
     72         return mNetworkNotified;
     73     }
     74 
     75     public void setIsPhone(boolean flag) {
     76         mIsPhone = flag;
     77     }
     78 
     79     @Override
     80     public boolean isPhone() {
     81         return mIsPhone;
     82     }
     83 
     84     public void setIsVoiceCapable(boolean flag) {
     85         mIsVoiceCapable = flag;
     86     }
     87 
     88     @Override
     89     public boolean isVoiceCapable() {
     90         return mIsVoiceCapable;
     91     }
     92 
     93     @Override
     94     public boolean onCreate() {
     95         boolean created = super.onCreate();
     96         if (mDataWipeEnabled) {
     97             synchronized (sDataWiped) {
     98                 if (!sDataWiped) {
     99                     sDataWiped = true;
    100                     wipeData();
    101                 }
    102             }
    103         }
    104         return created;
    105     }
    106 
    107     @Override
    108     protected boolean shouldThrowExceptionForInitializationError() {
    109         return true;
    110     }
    111 
    112     /** We'll use a static size for unit tests */
    113     @Override
    114     public int getMaxThumbnailDim() {
    115         return 96;
    116     }
    117 
    118     /** We'll use a static size for unit tests */
    119     @Override
    120     public int getMaxDisplayPhotoDim() {
    121         return 256;
    122     }
    123 
    124     @Override
    125     protected void scheduleBackgroundTask(int task) {
    126         performBackgroundTask(task, null);
    127     }
    128 
    129     @Override
    130     protected void scheduleBackgroundTask(int task, Object arg) {
    131         performBackgroundTask(task, arg);
    132     }
    133 
    134     @Override
    135     protected void updateLocaleInBackground() {
    136     }
    137 
    138     @Override
    139     protected void updateDirectoriesInBackground(boolean rescan) {
    140     }
    141 
    142     @Override
    143     protected Account getDefaultAccount() {
    144         if (mAccount == null) {
    145             mAccount = new Account("androidtest (at) gmail.com", "com.google");
    146         }
    147         return mAccount;
    148     }
    149 
    150     @Override
    151     protected boolean isContactsAccount(Account account) {
    152         return true;
    153     }
    154 
    155     /**
    156      * Creates a mock PhotoPriorityResolver
    157      */
    158     @Override
    159     PhotoPriorityResolver createPhotoPriorityResolver(Context context) {
    160         return new PhotoPriorityResolver(context) {
    161             @Override
    162             public synchronized int getPhotoPriority(String accountType) {
    163                 if ("cupcake".equals(accountType)) {
    164                     return 3;
    165                 }
    166                 if ("donut".equals(accountType)) {
    167                     return 2;
    168                 }
    169                 if ("froyo".equals(accountType)) {
    170                     return 1;
    171                 }
    172                 return 0;
    173             }
    174         };
    175     }
    176 
    177     @Override
    178     protected Locale getLocale() {
    179         return Locale.US;
    180     }
    181 
    182     @Override
    183     public boolean isWritableAccountWithDataSet(String accountType) {
    184         return !READ_ONLY_ACCOUNT_TYPE.equals(accountType);
    185     }
    186 
    187     public void prepareForFullAggregation(int maxContact) {
    188         SQLiteDatabase db = getDatabaseHelper(getContext()).getWritableDatabase();
    189         db.execSQL("UPDATE raw_contacts SET aggregation_mode=0,aggregation_needed=1;");
    190         long rowId =
    191             db.compileStatement("SELECT _id FROM raw_contacts LIMIT 1 OFFSET " + maxContact)
    192                 .simpleQueryForLong();
    193         db.execSQL("DELETE FROM raw_contacts WHERE _id > " + rowId + ";");
    194     }
    195 
    196     public long getRawContactCount() {
    197         SQLiteDatabase db = getDatabaseHelper(getContext()).getReadableDatabase();
    198         return db.compileStatement("SELECT COUNT(*) FROM raw_contacts").simpleQueryForLong();
    199     }
    200 
    201     public long getContactCount() {
    202         SQLiteDatabase db = getDatabaseHelper(getContext()).getReadableDatabase();
    203         return db.compileStatement("SELECT COUNT(*) FROM contacts").simpleQueryForLong();
    204     }
    205 
    206     @Override
    207     public void wipeData() {
    208         Log.i(TAG, "wipeData");
    209         super.wipeData();
    210         SQLiteDatabase db = getDatabaseHelper(getContext()).getWritableDatabase();
    211         db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('raw_contacts', 42)");
    212         db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('contacts', 2009)");
    213         db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('data', 777)");
    214 
    215         getContactDirectoryManagerForTest().scanAllPackages();
    216     }
    217 
    218     // Flags to remember which transaction callback has been called for which mode.
    219     private boolean mOnBeginTransactionInternalCalledInProfileMode;
    220     private boolean mOnCommitTransactionInternalCalledInProfileMode;
    221     private boolean mOnRollbackTransactionInternalCalledInProfileMode;
    222 
    223     private boolean mOnBeginTransactionInternalCalledInContactMode;
    224     private boolean mOnCommitTransactionInternalCalledInContactMode;
    225     private boolean mOnRollbackTransactionInternalCalledInContactMode;
    226 
    227     public void resetTrasactionCallbackCalledFlags() {
    228         mOnBeginTransactionInternalCalledInProfileMode = false;
    229         mOnCommitTransactionInternalCalledInProfileMode = false;
    230         mOnRollbackTransactionInternalCalledInProfileMode = false;
    231 
    232         mOnBeginTransactionInternalCalledInContactMode = false;
    233         mOnCommitTransactionInternalCalledInContactMode = false;
    234         mOnRollbackTransactionInternalCalledInContactMode = false;
    235     }
    236 
    237     @Override
    238     protected void onBeginTransactionInternal(boolean forProfile) {
    239         super.onBeginTransactionInternal(forProfile);
    240         if (forProfile) {
    241             mOnBeginTransactionInternalCalledInProfileMode = true;
    242         } else {
    243             mOnBeginTransactionInternalCalledInContactMode = true;
    244         }
    245     }
    246 
    247     @Override
    248     protected void onCommitTransactionInternal(boolean forProfile) {
    249         super.onCommitTransactionInternal(forProfile);
    250         if (forProfile) {
    251             mOnCommitTransactionInternalCalledInProfileMode = true;
    252         } else {
    253             mOnCommitTransactionInternalCalledInContactMode = true;
    254         }
    255     }
    256 
    257     @Override
    258     protected void onRollbackTransactionInternal(boolean forProfile) {
    259         super.onRollbackTransactionInternal(forProfile);
    260         if (forProfile) {
    261             mOnRollbackTransactionInternalCalledInProfileMode = true;
    262         } else {
    263             mOnRollbackTransactionInternalCalledInContactMode = true;
    264         }
    265     }
    266 
    267     public void assertCommitTransactionCalledForProfileMode() {
    268         Assert.assertTrue("begin", mOnBeginTransactionInternalCalledInProfileMode);
    269         Assert.assertTrue("commit", mOnCommitTransactionInternalCalledInProfileMode);
    270         Assert.assertFalse("rollback", mOnRollbackTransactionInternalCalledInProfileMode);
    271     }
    272 
    273     public void assertRollbackTransactionCalledForProfileMode() {
    274         Assert.assertTrue("begin", mOnBeginTransactionInternalCalledInProfileMode);
    275         Assert.assertFalse("commit", mOnCommitTransactionInternalCalledInProfileMode);
    276         Assert.assertTrue("rollback", mOnRollbackTransactionInternalCalledInProfileMode);
    277     }
    278 
    279     public void assertNoTransactionsForProfileMode() {
    280         Assert.assertFalse("begin", mOnBeginTransactionInternalCalledInProfileMode);
    281         Assert.assertFalse("commit", mOnCommitTransactionInternalCalledInProfileMode);
    282         Assert.assertFalse("rollback", mOnRollbackTransactionInternalCalledInProfileMode);
    283     }
    284 
    285 
    286     public void assertCommitTransactionCalledForContactMode() {
    287         Assert.assertTrue("begin", mOnBeginTransactionInternalCalledInContactMode);
    288         Assert.assertTrue("commit", mOnCommitTransactionInternalCalledInContactMode);
    289         Assert.assertFalse("rollback", mOnRollbackTransactionInternalCalledInContactMode);
    290     }
    291 
    292     public void assertRollbackTransactionCalledForContactMode() {
    293         Assert.assertTrue("begin", mOnBeginTransactionInternalCalledInContactMode);
    294         Assert.assertFalse("commit", mOnCommitTransactionInternalCalledInContactMode);
    295         Assert.assertTrue("rollback", mOnRollbackTransactionInternalCalledInContactMode);
    296     }
    297 }
    298