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