1f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov/* 2f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 3f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * 4f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * use this file except in compliance with the License. You may obtain a copy of 6f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * the License at 7f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * 8f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * 10f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * License for the specific language governing permissions and limitations under 14f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * the License 15f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 16f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovpackage com.android.providers.contacts; 17f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 18f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.content.ContentValues; 196d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikovimport android.content.Context; 20f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.Cursor; 21f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.sqlite.SQLiteDatabase; 22e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wangimport android.provider.ContactsContract; 23f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email; 24f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Nickname; 25f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization; 26f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone; 27f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName; 28f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.Data; 29f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.text.TextUtils; 3038210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DataColumns; 3138210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.MimetypesColumns; 3238210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns; 3338210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables; 34aa18c233fdec3359c5231d4a5f61188446bf5d6fZheng Fuimport com.android.providers.contacts.aggregation.AbstractContactAggregator; 3538210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki 36f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov/** 37f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Handles inserts and update for a specific Data type. 38f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 39f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovpublic abstract class DataRowHandler { 40f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 41b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang private static final String[] HASH_INPUT_COLUMNS = new String[] { 42e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang Data.DATA1, Data.DATA2}; 43b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang 44f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public interface DataDeleteQuery { 45f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final String TABLE = Tables.DATA_JOIN_MIMETYPES; 46f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 47f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final String[] CONCRETE_COLUMNS = new String[] { 48f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov DataColumns.CONCRETE_ID, 49f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov MimetypesColumns.MIMETYPE, 50f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.RAW_CONTACT_ID, 51f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.IS_PRIMARY, 52f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.DATA1, 53f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov }; 54f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 55f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final String[] COLUMNS = new String[] { 56f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data._ID, 57f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov MimetypesColumns.MIMETYPE, 58f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.RAW_CONTACT_ID, 59f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.IS_PRIMARY, 60f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.DATA1, 61f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov }; 62f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 63f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final int _ID = 0; 64f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final int MIMETYPE = 1; 65f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final int RAW_CONTACT_ID = 2; 66f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final int IS_PRIMARY = 3; 67f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public static final int DATA1 = 4; 68f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 69f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 70f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public interface DataUpdateQuery { 71f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String[] COLUMNS = { Data._ID, Data.RAW_CONTACT_ID, Data.MIMETYPE }; 72f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 73f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int _ID = 0; 74f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int RAW_CONTACT_ID = 1; 75f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int MIMETYPE = 2; 76f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 77f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 786d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov protected final Context mContext; 79f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected final ContactsDatabaseHelper mDbHelper; 80aa18c233fdec3359c5231d4a5f61188446bf5d6fZheng Fu protected final AbstractContactAggregator mContactAggregator; 81f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected String[] mSelectionArgs1 = new String[1]; 82f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected final String mMimetype; 83f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected long mMimetypeId; 84f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 85f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov @SuppressWarnings("all") 866d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov public DataRowHandler(Context context, ContactsDatabaseHelper dbHelper, 87aa18c233fdec3359c5231d4a5f61188446bf5d6fZheng Fu AbstractContactAggregator aggregator, String mimetype) { 886d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov mContext = context; 89f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper = dbHelper; 90f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mContactAggregator = aggregator; 91f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mMimetype = mimetype; 92f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 93f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // To ensure the data column position. This is dead code if properly configured. 94f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (StructuredName.DISPLAY_NAME != Data.DATA1 || Nickname.NAME != Data.DATA1 95f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov || Organization.COMPANY != Data.DATA1 || Phone.NUMBER != Data.DATA1 96f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov || Email.DATA != Data.DATA1) { 97f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov throw new AssertionError("Some of ContactsContract.CommonDataKinds class primary" 98f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + " data is not in DATA1 column"); 99f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 100f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 101f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 102f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected long getMimeTypeId() { 103f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (mMimetypeId == 0) { 104f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mMimetypeId = mDbHelper.getMimeTypeId(mMimetype); 105f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 106f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return mMimetypeId; 107f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 108f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 109f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 110f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Inserts a row into the {@link Data} table. 111f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 112f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId, 113f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContentValues values) { 114b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang // Generate hash_id from data1 and data2 columns. 115b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang // For photo, use data15 column instead of data1 and data2 to generate hash_id. 116b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang handleHashIdForInsert(values); 117f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final long dataId = db.insert(Tables.DATA, null, values); 118f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 119f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final Integer primary = values.getAsInteger(Data.IS_PRIMARY); 120f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final Integer superPrimary = values.getAsInteger(Data.IS_SUPER_PRIMARY); 121f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if ((primary != null && primary != 0) || (superPrimary != null && superPrimary != 0)) { 122f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final long mimeTypeId = getMimeTypeId(); 123f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId); 12408fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu txContext.markRawContactMetadataDirty(rawContactId, /* isMetadataSyncAdapter =*/false); 125f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 126f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // We also have to make sure that no other data item on this raw_contact is 127f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // configured super primary 128f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (superPrimary != null) { 129f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (superPrimary != 0) { 130f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId); 131f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else { 132f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.clearSuperPrimary(rawContactId, mimeTypeId); 133f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 134f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else { 135f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // if there is already another data item configured as super-primary, 136f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // take over the flag (which will automatically remove it from the other item) 137f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (mDbHelper.rawContactHasSuperPrimary(rawContactId, mimeTypeId)) { 138f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId); 139f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 140f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 141f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 142f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 143f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov if (containsSearchableColumns(values)) { 144f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov txContext.invalidateSearchIndexForRawContact(rawContactId); 145f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 146f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 147f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return dataId; 148f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 149f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 150f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 151f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Validates data and updates a {@link Data} row using the cursor, which contains 152f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * the current data. 153f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * 154f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @return true if update changed something 155f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 156f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public boolean update(SQLiteDatabase db, TransactionContext txContext, 15708fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu ContentValues values, Cursor c, boolean callerIsSyncAdapter, 15808fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu boolean callerIsMetadataSyncAdapter) { 159f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long dataId = c.getLong(DataUpdateQuery._ID); 160f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 161f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 16208fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu handlePrimaryAndSuperPrimary(txContext, values, dataId, rawContactId, 16308fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu callerIsMetadataSyncAdapter); 164b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang handleHashIdForUpdate(values, dataId); 165f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 166f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (values.size() > 0) { 167f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(dataId); 168f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov db.update(Tables.DATA, values, Data._ID + " =?", mSelectionArgs1); 169f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 170f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 171f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov if (containsSearchableColumns(values)) { 172f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov txContext.invalidateSearchIndexForRawContact(rawContactId); 173f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 174f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 1758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng txContext.markRawContactDirtyAndChanged(rawContactId, callerIsSyncAdapter); 176f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 177f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return true; 178f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 179f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 180f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov public boolean hasSearchableData() { 181f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov return false; 182f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 183f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 184f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov public boolean containsSearchableColumns(ContentValues values) { 185f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov return false; 186f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 187f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 188f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov public void appendSearchableData(SearchIndexManager.IndexBuilder builder) { 189f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 190f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 191f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 192b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang * Fetch data1, data2, and data15 from values if they exist, and generate hash_id 193b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang * if one of data1 and data2 columns is set, otherwise using data15 instead. 194b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang * hash_id is null if all of these three field is null. 195b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang * Add hash_id key to values. 196b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang */ 197b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang public void handleHashIdForInsert(ContentValues values) { 198b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang final String data1 = values.getAsString(Data.DATA1); 199b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang final String data2 = values.getAsString(Data.DATA2); 200e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang final String photoHashId= mDbHelper.getPhotoHashId(); 201e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang 202e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang String hashId; 203e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang if (ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE.equals(mMimetype)) { 204e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang hashId = photoHashId; 205e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang } else if (!TextUtils.isEmpty(data1) || !TextUtils.isEmpty(data2)) { 206e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang hashId = mDbHelper.generateHashId(data1, data2); 207e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang } else { 208e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang hashId = null; 209e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang } 210b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang if (TextUtils.isEmpty(hashId)) { 211b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang values.putNull(Data.HASH_ID); 212b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } else { 213b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang values.put(Data.HASH_ID, hashId); 214b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 215b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 216b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang 217b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang /** 218b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang * Compute hash_id column and add it to values. 219e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang * If this is not a photo field, and one of data1 and data2 changed, re-compute hash_id with new 220e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang * data1 and data2. 221e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang * If this is a photo field, no need to change hash_id. 222b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang */ 223b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang private void handleHashIdForUpdate(ContentValues values, long dataId) { 224e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang if (!ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE.equals(mMimetype) 225e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang && (values.containsKey(Data.DATA1) || values.containsKey(Data.DATA2))) { 22651cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang String data1 = values.getAsString(Data.DATA1); 22751cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang String data2 = values.getAsString(Data.DATA2); 228b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang mSelectionArgs1[0] = String.valueOf(dataId); 229b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang final Cursor c = mDbHelper.getReadableDatabase().query(Tables.DATA, 230b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang HASH_INPUT_COLUMNS, Data._ID + "=?", mSelectionArgs1, null, null, null); 231b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang try { 232b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang if (c.moveToFirst()) { 233b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang data1 = values.containsKey(Data.DATA1) ? data1 : c.getString(0); 234b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang data2 = values.containsKey(Data.DATA2) ? data2 : c.getString(1); 235b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 236b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } finally { 237b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang c.close(); 238b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 239e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang 240e8cdd9c437177da67ec41e24bc81e3c2d0a3efb3Tingting Wang String hashId = mDbHelper.generateHashId(data1, data2); 24151cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang if (TextUtils.isEmpty(hashId)) { 24251cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang values.putNull(Data.HASH_ID); 24351cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang } else { 24451cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang values.put(Data.HASH_ID, hashId); 24551cb9cf6158b7e077110f3d5a704a3b3673795b1Tingting Wang } 246b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 247b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang } 248b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang 249b712e3c95a1add30937dee5dddab429ce5247269Tingting Wang /** 250f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Ensures that all super-primary and primary flags of this raw_contact are 251f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * configured correctly 252f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 25308fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu private void handlePrimaryAndSuperPrimary(TransactionContext txContext, ContentValues values, 25408fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu long dataId, long rawContactId, boolean callerIsMetadataSyncAdapter) { 255ee1267f05b98218d26f39875949cbc66a8a9b71dJay Shrauner final boolean hasPrimary = values.getAsInteger(Data.IS_PRIMARY) != null; 256ee1267f05b98218d26f39875949cbc66a8a9b71dJay Shrauner final boolean hasSuperPrimary = values.getAsInteger(Data.IS_SUPER_PRIMARY) != null; 257f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 258f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Nothing to do? Bail out early 259f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!hasPrimary && !hasSuperPrimary) return; 260f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 26108fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu txContext.markRawContactMetadataDirty(rawContactId, callerIsMetadataSyncAdapter); 26208fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu 263f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final long mimeTypeId = getMimeTypeId(); 264f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 265f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Check if we want to clear values 266f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean clearPrimary = hasPrimary && 267f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.getAsInteger(Data.IS_PRIMARY) == 0; 268f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean clearSuperPrimary = hasSuperPrimary && 269f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.getAsInteger(Data.IS_SUPER_PRIMARY) == 0; 270f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 271f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (clearPrimary || clearSuperPrimary) { 272f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Test whether these values are currently set 273f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(dataId); 274f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final String[] cols = new String[] { Data.IS_PRIMARY, Data.IS_SUPER_PRIMARY }; 275f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final Cursor c = mDbHelper.getReadableDatabase().query(Tables.DATA, 276f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov cols, Data._ID + "=?", mSelectionArgs1, null, null, null); 277f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov try { 278f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (c.moveToFirst()) { 279f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean isPrimary = c.getInt(0) != 0; 280f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean isSuperPrimary = c.getInt(1) != 0; 281f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Clear values if they are currently set 282f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (isSuperPrimary) { 283f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.clearSuperPrimary(rawContactId, mimeTypeId); 284f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 285f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (clearPrimary && isPrimary) { 286f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsPrimary(rawContactId, -1, mimeTypeId); 287f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 288f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 289f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } finally { 290f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov c.close(); 291f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 292f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else { 293f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Check if we want to set values 294f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean setPrimary = hasPrimary && 295f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.getAsInteger(Data.IS_PRIMARY) != 0; 296f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final boolean setSuperPrimary = hasSuperPrimary && 297f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.getAsInteger(Data.IS_SUPER_PRIMARY) != 0; 298f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (setSuperPrimary) { 299f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Set both super primary and primary 300f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId); 301f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId); 302f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else if (setPrimary) { 303f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Primary was explicitly set, but super-primary was not. 304f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // In this case we set super-primary on this data item, if 305f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // any data item of the same raw-contact already is super-primary 306f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (mDbHelper.rawContactHasSuperPrimary(rawContactId, mimeTypeId)) { 307f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsSuperPrimary(rawContactId, dataId, mimeTypeId); 308f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 309f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsPrimary(rawContactId, dataId, mimeTypeId); 310f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 311f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 312f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 313f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // Now that we've taken care of clearing this, remove it from "values". 314f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.remove(Data.IS_SUPER_PRIMARY); 315f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.remove(Data.IS_PRIMARY); 316f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 317f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 318f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) { 319f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 320f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 321f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean primary = c.getInt(DataDeleteQuery.IS_PRIMARY) != 0; 322f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(dataId); 323f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int count = db.delete(Tables.DATA, Data._ID + "=?", mSelectionArgs1); 324f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(rawContactId); 325f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov db.delete(Tables.PRESENCE, PresenceColumns.RAW_CONTACT_ID + "=?", mSelectionArgs1); 326f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (count != 0 && primary) { 327f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov fixPrimary(db, rawContactId); 32808fb8384ccb36de3d3d046e287fe5c43c1f85fafZheng Fu txContext.markRawContactMetadataDirty(rawContactId, /* isMetadataSyncAdapter =*/false); 329f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 330f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 331f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov if (hasSearchableData()) { 332f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov txContext.invalidateSearchIndexForRawContact(rawContactId); 333f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 334f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 335f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return count; 336f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 337f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 338f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private void fixPrimary(SQLiteDatabase db, long rawContactId) { 339f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long mimeTypeId = getMimeTypeId(); 340f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long primaryId = -1; 341f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int primaryType = -1; 342f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(rawContactId); 343f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Cursor c = db.query(DataDeleteQuery.TABLE, 344f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov DataDeleteQuery.CONCRETE_COLUMNS, 345f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Data.RAW_CONTACT_ID + "=?" + 346f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov " AND " + DataColumns.MIMETYPE_ID + "=" + mimeTypeId, 347f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1, null, null, null); 348f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov try { 349f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov while (c.moveToNext()) { 350f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long dataId = c.getLong(DataDeleteQuery._ID); 351f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int type = c.getInt(DataDeleteQuery.DATA1); 352f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (primaryType == -1 || getTypeRank(type) < getTypeRank(primaryType)) { 353f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov primaryId = dataId; 354f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov primaryType = type; 355f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 356f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 357f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } finally { 358f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov c.close(); 359f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 360f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (primaryId != -1) { 361f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mDbHelper.setIsPrimary(rawContactId, primaryId, mimeTypeId); 362f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 363f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 364f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 365f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 366f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Returns the rank of a specific record type to be used in determining the primary 367f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * row. Lower number represents higher priority. 368f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 369f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected int getTypeRank(int type) { 370f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return 0; 371f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 372f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 373f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov protected void fixRawContactDisplayName(SQLiteDatabase db, TransactionContext txContext, 374f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId) { 375f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!isNewRawContact(txContext, rawContactId)) { 3768ab0b7a48efe540226253567bcf6fdbc487186a2Dmitri Plotnikov mDbHelper.updateRawContactDisplayName(db, rawContactId); 377f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mContactAggregator.updateDisplayNameForRawContact(db, rawContactId); 378f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 379f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 380f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 381f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private boolean isNewRawContact(TransactionContext txContext, long rawContactId) { 382f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return txContext.isNewRawContact(rawContactId); 383f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 384f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 385f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 386f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Return set of values, using current values at given {@link Data#_ID} 387f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * as baseline, but augmented with any updates. Returns null if there is 388f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * no change. 389f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 390f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public ContentValues getAugmentedValues(SQLiteDatabase db, long dataId, 391f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContentValues update) { 392f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean changing = false; 393f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final ContentValues values = new ContentValues(); 394f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(dataId); 395f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final Cursor cursor = db.query(Tables.DATA, null, Data._ID + "=?", 396f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1, null, null, null); 397f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov try { 398f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (cursor.moveToFirst()) { 399f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov for (int i = 0; i < cursor.getColumnCount(); i++) { 400f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final String key = cursor.getColumnName(i); 401f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final String value = cursor.getString(i); 402f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!changing && update.containsKey(key)) { 403f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Object newValue = update.get(key); 404f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String newString = newValue == null ? null : newValue.toString(); 405f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov changing |= !TextUtils.equals(newString, value); 406f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 407f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.put(key, value); 408f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 409f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 410f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } finally { 411f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov cursor.close(); 412f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 413f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!changing) { 414f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return null; 415f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 416f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 417f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.putAll(update); 418f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return values; 419f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 420f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 421bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov public void triggerAggregation(TransactionContext txContext, long rawContactId) { 422bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov mContactAggregator.triggerAggregation(txContext, rawContactId); 423f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 424f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 425f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 426f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Test all against {@link TextUtils#isEmpty(CharSequence)}. 427f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 428f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public boolean areAllEmpty(ContentValues values, String[] keys) { 429f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov for (String key : keys) { 430f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!TextUtils.isEmpty(values.getAsString(key))) { 431f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return false; 432f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 433f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 434f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return true; 435f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 436f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 437f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 438f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Returns true if a value (possibly null) is specified for at least one of the supplied keys. 439f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 440f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public boolean areAnySpecified(ContentValues values, String[] keys) { 441f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov for (String key : keys) { 442f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (values.containsKey(key)) { 443f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return true; 444f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 445f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 446f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return false; 447f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 448f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov} 449