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