1ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki/*
2ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * Copyright (C) 2012 The Android Open Source Project
3ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki *
4ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * Licensed under the Apache License, Version 2.0 (the "License");
5ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * you may not use this file except in compliance with the License.
6ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * You may obtain a copy of the License at
7ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki *
8ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki *      http://www.apache.org/licenses/LICENSE-2.0
9ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki *
10ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * Unless required by applicable law or agreed to in writing, software
11ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * distributed under the License is distributed on an "AS IS" BASIS,
12ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * See the License for the specific language governing permissions and
14ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * limitations under the License.
15ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki */
16ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
17ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukipackage com.android.providers.contacts;
18ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
19ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport static com.android.providers.contacts.TestUtils.cv;
20ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
21ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport com.google.android.collect.Lists;
22ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
23ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.content.ContentProviderOperation;
24ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.content.ContentValues;
25ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract;
26ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
27ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract.Contacts;
28ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract.Data;
29ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract.Profile;
30ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.provider.ContactsContract.RawContacts;
31ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.test.suitebuilder.annotation.LargeTest;
32ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport android.util.Log;
33ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
34ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukiimport java.util.ArrayList;
35ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
36ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki/**
37ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * Tests to make sure we're handling DB transactions properly in regard to two databases,
38ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki * the profile db and the contacts db.
39ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki */
40ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki@LargeTest
41ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onukipublic class ContactsProvider2TransactionTest extends BaseContactsProvider2Test {
42ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    private SynchronousContactsProvider2 mProvider;
43ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
44ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    @Override
45ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    protected void setUp() throws Exception {
46ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        super.setUp();
47ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
48ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider = (SynchronousContactsProvider2) getProvider();
49ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
50ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
51ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    @Override
52ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    protected void tearDown() throws Exception {
53ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        super.tearDown();
54ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
55ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider = null;
56ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
57ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
58ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
59ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Make sure we start/finish transactions on the right databases for insert.
60ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
61ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_insert() {
62ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
63ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ContentValues values = cv(RawContacts.LAST_TIME_CONTACTED, 12345);
64ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
65ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Insert a raw contact.
66ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
67ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(RawContacts.CONTENT_URI, values);
68ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
69ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure we only COMMIT on the contacts DB, but there was no transaction on the
70ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // profile db.
71ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
72ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertNoTransactionsForProfileMode();
73ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
74ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
75ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Insert a profile raw contact.
76ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
77ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(Profile.CONTENT_RAW_CONTACTS_URI, values);
78ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
79ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Even though we only touched the profile DB, we also start and finish a transaction
80ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // on the contacts db.  AbstractContactsProvider does that to avoid deadlocks.
81ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
82ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
83ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
84ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
85ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
86ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Make sure we start/finish transactions on the right databases for update.
87ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
88ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_update() {
89ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
90ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ContentValues values = cv(RawContacts.LAST_TIME_CONTACTED, 12345);
91ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
92ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure to create a raw contact and a profile raw contact.
93ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(RawContacts.CONTENT_URI, values);
94ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(Profile.CONTENT_RAW_CONTACTS_URI, values);
95ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
96ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        values.clear();
97ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        values.put(RawContacts.LAST_TIME_CONTACTED, 99999);
98ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
99ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Update all raw contacts.
100ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
101ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertTrue(mResolver.update(RawContacts.CONTENT_URI, values, null, null) > 0);
102ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
103ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure we only COMMIT on the contacts DB, but there was no transaction on the
104ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // profile db.
105ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
106ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertNoTransactionsForProfileMode();
107ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
108ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
109ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Update all profile raw contacts.
110ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
111ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertTrue(mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, values, null, null) > 0);
112ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
113ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Even though we only touched the profile DB, we also start and finish a transaction
114ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // on the contacts db.  AbstractContactsProvider does that to avoid deadlocks.
115ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
116ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
117ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
118ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
119ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
120ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Make sure we start/finish transactions on the right databases for delete.
121ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
122ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_delete() {
123ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
124ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ContentValues values = cv(RawContacts.LAST_TIME_CONTACTED, 12345);
125ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
126ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure to create a raw contact and a profile raw contact.
127ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(RawContacts.CONTENT_URI, values);
128ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.insert(Profile.CONTENT_RAW_CONTACTS_URI, values);
129ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
130ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Delete all raw contacts.
131ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
132ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertTrue(mResolver.delete(RawContacts.CONTENT_URI, null, null) > 0);
133ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
134ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure we only COMMIT on the contacts DB, but there was no transaction on the
135ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // profile db.
136ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
137ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertNoTransactionsForProfileMode();
138ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
139ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Delete all profile raw contact.
140ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
141ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertTrue(mResolver.delete(Profile.CONTENT_RAW_CONTACTS_URI, null, null) > 0);
142ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
143ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Even though we only touched the profile DB, we also start and finish a transaction
144ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // on the contacts db.  AbstractContactsProvider does that to avoid deadlocks.
145ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
146ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
147ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
148ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
149ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Make sure we start/finish transactions on the right databases for bulk insert.
150ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
151ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_bulkInsert() {
152ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
153ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ContentValues values = cv(RawContacts.LAST_TIME_CONTACTED, 12345);
154ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
155ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Insert a raw contact.
156ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
157ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.bulkInsert(RawContacts.CONTENT_URI, new ContentValues[] {values});
158ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
159ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Make sure we only COMMIT on the contacts DB, but there was no transaction on the
160ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // profile db.
161ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
162ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertNoTransactionsForProfileMode();
163ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
164ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
165ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Insert a profile raw contact.
166ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
167ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.bulkInsert(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[] {values});
168ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
169ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Even though we only touched the profile DB, we also start and finish a transaction
170ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // on the contacts db.  AbstractContactsProvider does that to avoid deadlocks.
171ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
172ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
173ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
174ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
175ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
176ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Add an operation to create a raw contact.
177ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
178ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    private static void addInsertContactOperations(ArrayList<ContentProviderOperation> ops) {
179ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ContentProviderOperation.Builder b;
180ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
181ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(RawContacts.STARRED, 1);
182ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(RawContacts.TIMES_CONTACTED, 200001);
183ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ops.add(b.build());
184ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
185ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b = ContentProviderOperation.newInsert(Data.CONTENT_URI);
186ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValueBackReference(Data.RAW_CONTACT_ID, ops.size() - 1);
187ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.DISPLAY_NAME, "Regular Contact");
188ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.GIVEN_NAME, "Regular");
189ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.FAMILY_NAME, "Contact");
190ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
191ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ops.add(b.build());
192ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
193ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
194ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
195ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Check for a contact created that'll be created for {@link #addInsertContactOperations}.
196ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
197ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    private void checkStoredContact() {
198ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertStoredValues(Contacts.CONTENT_URI, cv(
199ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                Contacts.DISPLAY_NAME, "Regular Contact",
200ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                RawContacts.TIMES_CONTACTED, 200001
201ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                ));
202ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
203ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
204ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
205ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Add an operation to create a profile raw contact.
206ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
207ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    private static void addInsertProfileOperations(ArrayList<ContentProviderOperation> ops) {
208ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ContentProviderOperation.Builder b;
209ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b = ContentProviderOperation.newInsert(Profile.CONTENT_RAW_CONTACTS_URI);
210ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(RawContacts.STARRED, 1);
211ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(RawContacts.TIMES_CONTACTED, 100001);
212ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ops.add(b.build());
213ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
214ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b = ContentProviderOperation.newInsert(Data.CONTENT_URI);
215ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValueBackReference(Data.RAW_CONTACT_ID, ops.size() - 1);
216ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.DISPLAY_NAME, "Profile Contact");
217ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.GIVEN_NAME, "Profile");
218ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(StructuredName.FAMILY_NAME, "Contact");
219ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        b.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
220ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        ops.add(b.build());
221ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
222ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
223ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    /**
224ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * Check for a profile contact created that'll be created for
225ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     * {@link #addInsertProfileOperations}.
226ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki     */
227ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    private void checkStoredProfile() {
228ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        assertStoredValues(Profile.CONTENT_URI, cv(
229ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                Contacts.DISPLAY_NAME, "Profile Contact",
230ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                RawContacts.TIMES_CONTACTED, 100001
231ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki                ));
232ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
233ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
234ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_contactBatch() throws Exception {
235ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
236ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
237ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertContactOperations(ops);
238ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
239ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
240ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
241ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Execute the operations.
242ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
243ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
244ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Check the result
245ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
246ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertNoTransactionsForProfileMode();
247ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
248ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredContact();
249ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
250ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
251ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_profileBatch() throws Exception {
252ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
253ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
254ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertProfileOperations(ops);
255ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
256ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
257ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
258ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Execute the operations.
259ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
260ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
261ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Check the result
262ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
263ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
264ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
265ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredProfile();
266ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
267ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
268ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_mixedBatch() throws Exception {
269ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
270ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
271ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Create a raw contact and a profile raw contact in a single batch.
272ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
273ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertContactOperations(ops);
274ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertProfileOperations(ops);
275ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
276ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
277ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
278ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Execute the operations.
279ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
280ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
281ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Check the result
282ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
283ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
284ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
285ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredProfile();
286ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredContact();
287ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
288ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
289ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    public void testTransactionCallback_mixedBatchReversed() throws Exception {
290ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        final ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
291ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
292ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Create a profile raw contact and a raw contact in a single batch.
293ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
294ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertProfileOperations(ops);
295ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        addInsertContactOperations(ops);
296ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
297ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.resetTrasactionCallbackCalledFlags();
298ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
299ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Execute the operations.
300ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
301ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
302ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        // Check the result
303ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForContactMode();
304ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        mProvider.assertCommitTransactionCalledForProfileMode();
305ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki
306ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredProfile();
307ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        checkStoredContact();
308ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki    }
309ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki}
310