DataRowHandlerForGroupMembership.java revision 6d9702cec82fd27a1c3093c64df9dcc22744899a
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 com.android.providers.contacts.ContactsDatabaseHelper.Clauses; 19f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.DataColumns; 20f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.GroupsColumns; 21f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.Tables; 22f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport com.android.providers.contacts.ContactsProvider2.GroupIdCacheEntry; 23f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 24f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.accounts.Account; 25f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.content.ContentValues; 266d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikovimport android.content.Context; 27f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.Cursor; 28f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.DatabaseUtils; 29f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.database.sqlite.SQLiteDatabase; 30f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership; 31f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.Groups; 32f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts; 33f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport android.text.TextUtils; 34f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 35f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport java.util.ArrayList; 36f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovimport java.util.HashMap; 37f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 38f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov/** 39f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Handler for group membership data rows. 40f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 41f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikovpublic class DataRowHandlerForGroupMembership extends DataRowHandler { 42f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 43f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov interface RawContactsQuery { 44f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String TABLE = Tables.RAW_CONTACTS; 45f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 46f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String[] COLUMNS = new String[] { 47f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov RawContacts.DELETED, 48f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov RawContacts.ACCOUNT_TYPE, 49f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov RawContacts.ACCOUNT_NAME, 50f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov }; 51f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 52f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int DELETED = 0; 53f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int ACCOUNT_TYPE = 1; 54f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int ACCOUNT_NAME = 2; 55f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 56f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 57f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private static final String SELECTION_RAW_CONTACT_ID = RawContacts._ID + "=?"; 58f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 59f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private static final String QUERY_COUNT_FAVORITES_GROUP_MEMBERSHIPS_BY_RAW_CONTACT_ID = 60f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov "SELECT COUNT(*) FROM " + Tables.DATA + " LEFT OUTER JOIN " + Tables .GROUPS 61f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + " ON " + Tables.DATA + "." + GroupMembership.GROUP_ROW_ID 62f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "=" + GroupsColumns.CONCRETE_ID 63f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + " WHERE " + DataColumns.MIMETYPE_ID + "=?" 64f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + " AND " + Tables.DATA + "." + GroupMembership.RAW_CONTACT_ID + "=?" 65f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + " AND " + Groups.FAVORITES + "!=0"; 66f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 67f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private final HashMap<String, ArrayList<GroupIdCacheEntry>> mGroupIdCache; 68f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 696d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov public DataRowHandlerForGroupMembership(Context context, ContactsDatabaseHelper dbHelper, 70f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContactAggregator aggregator, 71f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov HashMap<String, ArrayList<GroupIdCacheEntry>> groupIdCache) { 726d9702cec82fd27a1c3093c64df9dcc22744899aDmitri Plotnikov super(context, dbHelper, aggregator, GroupMembership.CONTENT_ITEM_TYPE); 73f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mGroupIdCache = groupIdCache; 74f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 75f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 76f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov @Override 77f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public long insert(SQLiteDatabase db, TransactionContext txContext, long rawContactId, 78f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContentValues values) { 79f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov resolveGroupSourceIdInValues(txContext, rawContactId, db, values, true); 80f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long dataId = super.insert(db, txContext, rawContactId, values); 81f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (hasFavoritesGroupMembership(db, rawContactId)) { 82f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateRawContactsStar(db, rawContactId, true /* starred */); 83f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 84f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateVisibility(rawContactId); 85f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return dataId; 86f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 87f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 88f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov @Override 89f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public boolean update(SQLiteDatabase db, TransactionContext txContext, ContentValues values, 90f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Cursor c, boolean callerIsSyncAdapter) { 91f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId = c.getLong(DataUpdateQuery.RAW_CONTACT_ID); 92f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean wasStarred = hasFavoritesGroupMembership(db, rawContactId); 93f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov resolveGroupSourceIdInValues(txContext, rawContactId, db, values, false); 94f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!super.update(db, txContext, values, c, callerIsSyncAdapter)) { 95f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return false; 96f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 97f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean isStarred = hasFavoritesGroupMembership(db, rawContactId); 98f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (wasStarred != isStarred) { 99f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateRawContactsStar(db, rawContactId, isStarred); 100f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 101f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateVisibility(rawContactId); 102f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return true; 103f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 104f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 105f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private void updateRawContactsStar(SQLiteDatabase db, long rawContactId, boolean starred) { 106f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContentValues rawContactValues = new ContentValues(); 107f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov rawContactValues.put(RawContacts.STARRED, starred ? 1 : 0); 108f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (db.update(Tables.RAW_CONTACTS, rawContactValues, SELECTION_RAW_CONTACT_ID, 109f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov new String[]{Long.toString(rawContactId)}) > 0) { 110f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mContactAggregator.updateStarred(rawContactId); 111f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 112f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 113f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 114f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private boolean hasFavoritesGroupMembership(SQLiteDatabase db, long rawContactId) { 115f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // TODO compiled SQL statement 116f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final long groupMembershipMimetypeId = mDbHelper 117f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov .getMimeTypeId(GroupMembership.CONTENT_ITEM_TYPE); 118f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean isStarred = 0 < DatabaseUtils 119f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov .longForQuery(db, QUERY_COUNT_FAVORITES_GROUP_MEMBERSHIPS_BY_RAW_CONTACT_ID, 120f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov new String[]{Long.toString(groupMembershipMimetypeId), Long.toString(rawContactId)}); 121f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return isStarred; 122f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 123f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 124f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov @Override 125f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov public int delete(SQLiteDatabase db, TransactionContext txContext, Cursor c) { 126f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId = c.getLong(DataDeleteQuery.RAW_CONTACT_ID); 127f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean wasStarred = hasFavoritesGroupMembership(db, rawContactId); 128f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int count = super.delete(db, txContext, c); 129f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean isStarred = hasFavoritesGroupMembership(db, rawContactId); 130f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (wasStarred && !isStarred) { 131f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateRawContactsStar(db, rawContactId, false /* starred */); 132f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 133f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov updateVisibility(rawContactId); 134f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return count; 135f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 136f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 137f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private void updateVisibility(long rawContactId) { 138f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long contactId = mDbHelper.getContactId(rawContactId); 139f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (contactId == 0) { 140f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov return; 141f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov } 142f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov 143f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov if (mDbHelper.updateContactVisibleOnlyIfChanged(contactId)) { 144f266e8c568905337960b1fec5379841585af92a7Dmitri Plotnikov mContactAggregator.updateAggregationAfterVisibilityChange(contactId); 145f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 146f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 147f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 148f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private void resolveGroupSourceIdInValues(TransactionContext txContext, 149f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long rawContactId, SQLiteDatabase db, ContentValues values, boolean isInsert) { 150f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean containsGroupSourceId = values.containsKey(GroupMembership.GROUP_SOURCE_ID); 151f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov boolean containsGroupId = values.containsKey(GroupMembership.GROUP_ROW_ID); 152f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (containsGroupSourceId && containsGroupId) { 153f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov throw new IllegalArgumentException( 154f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov "you are not allowed to set both the GroupMembership.GROUP_SOURCE_ID " 155f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "and GroupMembership.GROUP_ROW_ID"); 156f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 157f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 158f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!containsGroupSourceId && !containsGroupId) { 159f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (isInsert) { 160f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov throw new IllegalArgumentException( 161f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov "you must set exactly one of GroupMembership.GROUP_SOURCE_ID " 162f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "and GroupMembership.GROUP_ROW_ID"); 163f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else { 164f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return; 165f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 166f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 167f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 168f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (containsGroupSourceId) { 169f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final String sourceId = values.getAsString(GroupMembership.GROUP_SOURCE_ID); 170f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov final long groupId = getOrMakeGroup(db, rawContactId, sourceId, 171f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov txContext.getAccountForRawContact(rawContactId)); 172f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.remove(GroupMembership.GROUP_SOURCE_ID); 173f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov values.put(GroupMembership.GROUP_ROW_ID, groupId); 174f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 175f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 176f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 177f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov /** 178f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * Returns the group id of the group with sourceId and the same account as rawContactId. 179f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * If the group doesn't already exist then it is first created, 180f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @param db SQLiteDatabase to use for this operation 181f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @param rawContactId the contact this group is associated with 182f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @param sourceId the sourceIf of the group to query or create 183f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @return the group id of the existing or created group 184f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @throws IllegalArgumentException if the contact is not associated with an account 185f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov * @throws IllegalStateException if a group needs to be created but the creation failed 186f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov */ 187f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov private long getOrMakeGroup(SQLiteDatabase db, long rawContactId, String sourceId, 188f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Account account) { 189f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 190f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (account == null) { 191f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mSelectionArgs1[0] = String.valueOf(rawContactId); 192f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Cursor c = db.query(RawContactsQuery.TABLE, RawContactsQuery.COLUMNS, 193f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov RawContacts._ID + "=?", mSelectionArgs1, null, null, null); 194f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov try { 195f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (c.moveToFirst()) { 196f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String accountName = c.getString(RawContactsQuery.ACCOUNT_NAME); 197f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov String accountType = c.getString(RawContactsQuery.ACCOUNT_TYPE); 198f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) { 199f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov account = new Account(accountName, accountType); 200f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 201f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 202f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } finally { 203f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov c.close(); 204f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 205f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 206f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 207f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (account == null) { 208f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov throw new IllegalArgumentException("if the groupmembership only " 209f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "has a sourceid the the contact must be associated with " 210f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "an account"); 211f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 212f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 213f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ArrayList<GroupIdCacheEntry> entries = mGroupIdCache.get(sourceId); 214f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (entries == null) { 215f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entries = new ArrayList<GroupIdCacheEntry>(1); 216f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov mGroupIdCache.put(sourceId, entries); 217f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 218f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 219f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov int count = entries.size(); 220f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov for (int i = 0; i < count; i++) { 221f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov GroupIdCacheEntry entry = entries.get(i); 222f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (entry.accountName.equals(account.name) && entry.accountType.equals(account.type)) { 223f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return entry.groupId; 224f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 225f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 226f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 227f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov GroupIdCacheEntry entry = new GroupIdCacheEntry(); 228f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entry.accountName = account.name; 229f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entry.accountType = account.type; 230f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entry.sourceId = sourceId; 231f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entries.add(0, entry); 232f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 233f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // look up the group that contains this sourceId and has the same account name and type 234f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov // as the contact refered to by rawContactId 235f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Cursor c = db.query(Tables.GROUPS, new String[]{RawContacts._ID}, 236f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov Clauses.GROUP_HAS_ACCOUNT_AND_SOURCE_ID, 237f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov new String[]{sourceId, account.name, account.type}, null, null, null); 238f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov try { 239f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (c.moveToFirst()) { 240f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entry.groupId = c.getLong(0); 241f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } else { 242f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov ContentValues groupValues = new ContentValues(); 243f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov groupValues.put(Groups.ACCOUNT_NAME, account.name); 244f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov groupValues.put(Groups.ACCOUNT_TYPE, account.type); 245f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov groupValues.put(Groups.SOURCE_ID, sourceId); 246f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov long groupId = db.insert(Tables.GROUPS, Groups.ACCOUNT_NAME, groupValues); 247f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov if (groupId < 0) { 248f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov throw new IllegalStateException("unable to create a new group with " 249f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov + "this sourceid: " + groupValues); 250f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 251f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov entry.groupId = groupId; 252f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 253f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } finally { 254f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov c.close(); 255f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 256f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov 257f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov return entry.groupId; 258f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov } 259f6d4922f664127d0455b45b1f7444c4553581282Dmitri Plotnikov} 260