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 23 import java.util.Locale; 24 25 /** 26 * A version of {@link ContactsProvider2} class that performs aggregation 27 * synchronously and wipes all data at construction time. 28 */ 29 public class SynchronousContactsProvider2 extends ContactsProvider2 { 30 public static final String READ_ONLY_ACCOUNT_TYPE = "ro"; 31 32 private static Boolean sDataWiped = false; 33 private static ContactsDatabaseHelper mDbHelper; 34 private boolean mDataWipeEnabled = true; 35 private Account mAccount; 36 private boolean mNetworkNotified; 37 private boolean mIsPhone = true; 38 39 @Override 40 protected ContactsDatabaseHelper getDatabaseHelper(final Context context) { 41 if (mDbHelper == null) { 42 mDbHelper = new ContactsDatabaseHelper(context); 43 } 44 return mDbHelper; 45 } 46 47 @Override 48 public ProfileProvider getProfileProvider() { 49 return new SynchronousProfileProvider(this); 50 } 51 52 public static void resetOpenHelper() { 53 mDbHelper = null; 54 SynchronousProfileProvider.resetOpenHelper(); 55 } 56 57 public void setDataWipeEnabled(boolean flag) { 58 mDataWipeEnabled = flag; 59 } 60 61 @Override 62 public void onBegin() { 63 super.onBegin(); 64 mNetworkNotified = false; 65 } 66 67 @Override 68 protected void notifyChange(boolean syncToNetwork) { 69 mNetworkNotified |= syncToNetwork; 70 } 71 72 public boolean isNetworkNotified() { 73 return mNetworkNotified; 74 } 75 76 public void setIsPhone(boolean flag) { 77 mIsPhone = flag; 78 } 79 80 @Override 81 public boolean isPhone() { 82 return mIsPhone; 83 } 84 85 @Override 86 public boolean onCreate() { 87 boolean created = super.onCreate(); 88 if (mDataWipeEnabled) { 89 synchronized (sDataWiped) { 90 if (!sDataWiped) { 91 sDataWiped = true; 92 wipeData(); 93 } 94 } 95 } 96 return created; 97 } 98 99 @Override 100 protected void scheduleBackgroundTask(int task) { 101 performBackgroundTask(task, null); 102 } 103 104 @Override 105 protected void scheduleBackgroundTask(int task, Object arg) { 106 performBackgroundTask(task, arg); 107 } 108 109 @Override 110 protected void updateLocaleInBackground() { 111 } 112 113 @Override 114 protected void updateDirectoriesInBackground(boolean rescan) { 115 } 116 117 @Override 118 protected Account getDefaultAccount() { 119 if (mAccount == null) { 120 mAccount = new Account("androidtest (at) gmail.com", "com.google"); 121 } 122 return mAccount; 123 } 124 125 @Override 126 protected boolean isContactsAccount(Account account) { 127 return true; 128 } 129 130 /** 131 * Creates a mock PhotoPriorityResolver 132 */ 133 @Override 134 PhotoPriorityResolver createPhotoPriorityResolver(Context context) { 135 return new PhotoPriorityResolver(context) { 136 @Override 137 public synchronized int getPhotoPriority(String accountType) { 138 if ("cupcake".equals(accountType)) { 139 return 3; 140 } 141 if ("donut".equals(accountType)) { 142 return 2; 143 } 144 if ("froyo".equals(accountType)) { 145 return 1; 146 } 147 return 0; 148 } 149 }; 150 } 151 152 @Override 153 protected Locale getLocale() { 154 return Locale.US; 155 } 156 157 @Override 158 protected boolean isWritableAccountWithDataSet(String accountType) { 159 return !READ_ONLY_ACCOUNT_TYPE.equals(accountType); 160 } 161 162 public void prepareForFullAggregation(int maxContact) { 163 SQLiteDatabase db = getDatabaseHelper(getContext()).getWritableDatabase(); 164 db.execSQL("UPDATE raw_contacts SET aggregation_mode=0,aggregation_needed=1;"); 165 long rowId = 166 db.compileStatement("SELECT _id FROM raw_contacts LIMIT 1 OFFSET " + maxContact) 167 .simpleQueryForLong(); 168 db.execSQL("DELETE FROM raw_contacts WHERE _id > " + rowId + ";"); 169 } 170 171 public long getRawContactCount() { 172 SQLiteDatabase db = getDatabaseHelper(getContext()).getReadableDatabase(); 173 return db.compileStatement("SELECT COUNT(*) FROM raw_contacts").simpleQueryForLong(); 174 } 175 176 public long getContactCount() { 177 SQLiteDatabase db = getDatabaseHelper(getContext()).getReadableDatabase(); 178 return db.compileStatement("SELECT COUNT(*) FROM contacts").simpleQueryForLong(); 179 } 180 181 @Override 182 public void wipeData() { 183 super.wipeData(); 184 SQLiteDatabase db = getDatabaseHelper(getContext()).getWritableDatabase(); 185 db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('raw_contacts', 42)"); 186 db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('contacts', 2009)"); 187 db.execSQL("replace into SQLITE_SEQUENCE (name,seq) values('data', 777)"); 188 189 getContactDirectoryManagerForTest().scanAllPackages(); 190 } 191 192 @Override 193 protected boolean isLegacyContactImportNeeded() { 194 195 // We have an explicit test for data conversion - no need to do it every time 196 return false; 197 } 198 } 199