1d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov/* 2d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project 3d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * 4d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License"); 5d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * you may not use this file except in compliance with the License. 6d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * You may obtain a copy of the License at 7d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * 8d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * http://www.apache.org/licenses/LICENSE-2.0 9d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * 10d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software 11d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS, 12d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * See the License for the specific language governing permissions and 14d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * limitations under the License 15d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov */ 16d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 17d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovpackage com.android.providers.contacts; 18d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 19d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport com.google.android.collect.Maps; 20d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport com.google.android.collect.Sets; 21d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 22d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport java.util.HashMap; 23d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport java.util.HashSet; 24d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport java.util.Map.Entry; 25d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovimport java.util.Set; 26d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 27d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov/** 28d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * Accumulates information for an entire transaction. {@link ContactsProvider2} consumes 29d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov * it at commit time. 30d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov */ 31d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikovpublic class TransactionContext { 32d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 335d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro private final boolean mForProfile; 349d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki /** Map from raw contact id to account Id */ 350992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashMap<Long, Long> mInsertedRawContactsAccounts; 360992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashSet<Long> mUpdatedRawContacts; 370992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashSet<Long> mDirtyRawContacts; 388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng // Set used to track what has been changed and deleted. This is needed so we can update the 398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng // contact last touch timestamp. Dirty set above is only set when sync adapter is false. 408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng // {@see android.provider.ContactsContract#CALLER_IS_SYNCADAPTER}. While the set below will 418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng // contain all changed contacts. 428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng private HashSet<Long> mChangedRawContacts; 430992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashSet<Long> mStaleSearchIndexRawContacts; 440992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashSet<Long> mStaleSearchIndexContacts; 450992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki private HashMap<Long, Object> mUpdatedSyncStates; 46d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 475d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public TransactionContext(boolean forProfile) { 485d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro mForProfile = forProfile; 495d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro } 505d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 515d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro public boolean isForProfile() { 525d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro return mForProfile; 535d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro } 545d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro 559d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki public void rawContactInserted(long rawContactId, long accountId) { 560992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap(); 579d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki mInsertedRawContactsAccounts.put(rawContactId, accountId); 588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng 598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng markRawContactChangedOrDeletedOrInserted(rawContactId); 60d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 61d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 62d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public void rawContactUpdated(long rawContactId) { 630992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mUpdatedRawContacts == null) mUpdatedRawContacts = Sets.newHashSet(); 64d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov mUpdatedRawContacts.add(rawContactId); 65d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 66d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng public void markRawContactDirtyAndChanged(long rawContactId, boolean isSyncAdapter) { 688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng if (!isSyncAdapter) { 698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng if (mDirtyRawContacts == null) { 708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng mDirtyRawContacts = Sets.newHashSet(); 718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng } 728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng mDirtyRawContacts.add(rawContactId); 738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng } 748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng 758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng markRawContactChangedOrDeletedOrInserted(rawContactId); 768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng } 778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng 788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng public void markRawContactChangedOrDeletedOrInserted(long rawContactId) { 798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng if (mChangedRawContacts == null) { 808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng mChangedRawContacts = Sets.newHashSet(); 818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng } 828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng mChangedRawContacts.add(rawContactId); 83d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 84d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 85d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public void syncStateUpdated(long rowId, Object data) { 860992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mUpdatedSyncStates == null) mUpdatedSyncStates = Maps.newHashMap(); 87d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov mUpdatedSyncStates.put(rowId, data); 88d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 89d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 90f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov public void invalidateSearchIndexForRawContact(long rawContactId) { 910992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = Sets.newHashSet(); 92f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov mStaleSearchIndexRawContacts.add(rawContactId); 93f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 94f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 95bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov public void invalidateSearchIndexForContact(long contactId) { 960992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = Sets.newHashSet(); 97bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov mStaleSearchIndexContacts.add(contactId); 98bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov } 99bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov 100d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public Set<Long> getInsertedRawContactIds() { 1010992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap(); 1029d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki return mInsertedRawContactsAccounts.keySet(); 103d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 104d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 105d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public Set<Long> getUpdatedRawContactIds() { 1060992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mUpdatedRawContacts == null) mUpdatedRawContacts = Sets.newHashSet(); 107d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov return mUpdatedRawContacts; 108d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 109d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 11024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro public Set<Long> getDirtyRawContactIds() { 1110992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mDirtyRawContacts == null) mDirtyRawContacts = Sets.newHashSet(); 11224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro return mDirtyRawContacts; 11324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro } 11424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro 1158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng public Set<Long> getChangedRawContactIds() { 1168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng if (mChangedRawContacts == null) mChangedRawContacts = Sets.newHashSet(); 1178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng return mChangedRawContacts; 1188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng } 1198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng 120f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov public Set<Long> getStaleSearchIndexRawContactIds() { 1210992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mStaleSearchIndexRawContacts == null) mStaleSearchIndexRawContacts = Sets.newHashSet(); 122f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov return mStaleSearchIndexRawContacts; 123f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov } 124f262d56495ac4ea30d31bd050efb116bd4bb4235Dmitri Plotnikov 125bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov public Set<Long> getStaleSearchIndexContactIds() { 1260992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mStaleSearchIndexContacts == null) mStaleSearchIndexContacts = Sets.newHashSet(); 127bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov return mStaleSearchIndexContacts; 128bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov } 129bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov 130d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public Set<Entry<Long, Object>> getUpdatedSyncStates() { 1310992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mUpdatedSyncStates == null) mUpdatedSyncStates = Maps.newHashMap(); 132d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov return mUpdatedSyncStates.entrySet(); 133d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 134d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 1359d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki public Long getAccountIdOrNullForRawContact(long rawContactId) { 1360992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap(); 1379d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki return mInsertedRawContactsAccounts.get(rawContactId); 138d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 139d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 140d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov public boolean isNewRawContact(long rawContactId) { 1410992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki if (mInsertedRawContactsAccounts == null) mInsertedRawContactsAccounts = Maps.newHashMap(); 1429d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki return mInsertedRawContactsAccounts.containsKey(rawContactId); 143d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 144d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov 1450992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki public void clearExceptSearchIndexUpdates() { 1460992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mInsertedRawContactsAccounts = null; 1470992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mUpdatedRawContacts = null; 1480992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mUpdatedSyncStates = null; 1490992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mDirtyRawContacts = null; 1508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng mChangedRawContacts = null; 151bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov } 152bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov 153bd9abbb6b03b4ec1e28ad3fa2fcba5d1eb8609eaDmitri Plotnikov public void clearSearchIndexUpdates() { 1540992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mStaleSearchIndexRawContacts = null; 1550992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki mStaleSearchIndexContacts = null; 1560992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki } 1570992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki 1580992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki public void clearAll() { 1590992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki clearExceptSearchIndexUpdates(); 1600992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki clearSearchIndexUpdates(); 161d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov } 162d364d74ce9cc677c10362b8686d7c33fafe78bebDmitri Plotnikov} 163