ContactsProvider2Test.java revision 4928b8c8c7a49ec088884cd9d330eeecc811dca9
1d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/*
2d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project
3d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
4d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
5d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * you may not use this file except in compliance with the License.
6d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * You may obtain a copy of the License at
7d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
8d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
9d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
10d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
12d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * See the License for the specific language governing permissions and
14d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * limitations under the License.
15d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
168920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens
1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts;
18d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
19d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport com.android.internal.util.ArrayUtils;
20dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
21f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawaimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
22b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
23f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport com.android.providers.contacts.tests.R;
2424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport com.google.android.collect.Lists;
25d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wongimport android.accounts.Account;
27d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderOperation;
28d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderResult;
29d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentUris;
30d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentValues;
319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.content.Entity;
3233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.content.EntityIterator;
3342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport android.content.res.AssetFileDescriptor;
34d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.database.Cursor;
35f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawaimport android.database.sqlite.SQLiteDatabase;
36d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.net.Uri;
37c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract;
38d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
39dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
40dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
41dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
42dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
43dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
44dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
45dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
46dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
47ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikovimport android.provider.ContactsContract.ContactCounts;
48c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.provider.ContactsContract.Data;
5046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawaimport android.provider.ContactsContract.DataUsageFeedback;
51dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.Directory;
525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
53f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.DisplayPhoto;
547a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.ContactsContract.Groups;
564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
5824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
5909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
6033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6162318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
62916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikovimport android.provider.ContactsContract.SearchSnippetColumns;
6389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
6482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
66f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
67dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.LiveFolders;
68dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
697d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
70d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
71f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
72d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
7342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
7442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
75ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringertimport java.io.InputStream;
76f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
83d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
84d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
85d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
86d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
87d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
888920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
8928f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
90d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
91d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
92d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
93d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
94d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
9547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_1 = new Account("account_name_1", "account_type_1");
9647fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_2 = new Account("account_name_2", "account_type_2");
9747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
98dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
99dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
100dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
101dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
102dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
103dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
104dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
105dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
106dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
107dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
108dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
109dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
110dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
111dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
112dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
113f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1143d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1153d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
116dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
117dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
118dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
11924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
120dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
121dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
122dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
123dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
124dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
125dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
126dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
127dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
128dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
129dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
133dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
134dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
135dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
136dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
137dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
138dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
139dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
140dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
142dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
143dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
144dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
147dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
148f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1493d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1503d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
151dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
152dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
153dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
15424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
155dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
156dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
157dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
158dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
159dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
160dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
161dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
162dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
163dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
164dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
16530cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
166dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
167dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
168dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
169dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
170dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
171dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
172dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
173dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
174dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
175dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
176dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
17724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
178dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
179dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
180dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
181dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
182dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
183dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
184dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
185dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
186dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
187dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
188dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
189dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
190dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
191dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
192dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
193dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
194dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
195dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
196dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
197dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
198dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
199dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
200dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
201dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
202dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
203dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
204dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
205dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
206dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
207dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
208dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
209dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
210dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
211dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
212dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
213dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
214dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
215dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
216dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
217dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
218dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
219dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
220dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
221dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
222dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
223dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
224dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
225dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
226dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
227dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
228dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
229dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
230dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
231dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
232dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
233dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
234dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
235dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
236dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
237dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
238dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
239dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
240dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
241dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
242dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
24324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
244dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
245dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
246dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
251dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
252dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
253dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
254dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
255dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
257f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2583d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2593d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
260dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
261dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
264cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
265dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
267dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
268dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
269dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
272dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
273dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
274dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
278dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
283dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
284dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
288dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
295dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
298dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
299dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
309dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
310dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
311dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
31224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
313dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3273d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3283d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
329cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
344a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
345a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
346a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
347a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
348a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
349a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
350a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
351a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
352a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
353a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
354a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
355a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
356a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
357a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
358a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
359a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
360a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
361a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
362a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
363a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
364a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
365a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
366a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
367a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
368a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
380a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
381a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
383a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
385a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
386a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
387a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
388a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
389a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
390a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
391a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
392a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
393a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
394a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
395a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
396a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
397a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
398a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
399a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
400a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
402a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
403a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
404a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
405a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
406a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
407a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
408f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4093d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
411a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
412a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
41324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
414a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
415a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
416cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
417a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
418a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
419a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
420a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
421a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
422a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
423a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
424a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
425a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
426a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
427a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
428dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
44524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
446dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
449dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
450dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
451dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
460dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
461dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
462dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
463dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
466dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
470dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
471dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
472dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
482dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
483dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
484dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
4853d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
4863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
487dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
488dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
489dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
490dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
491dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
492dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
4932530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
494dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
495dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
496dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
497dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
498dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
499dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
500dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
501dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
502dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
503dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
504dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
505dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
506dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
507dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
508dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
509dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
510dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
511dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
51277c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION,
51377c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION_URI,
514dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
515dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
516dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
517c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
518dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
519dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
520dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
521dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
522dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
523dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
524dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
525dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
526dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
527dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
528dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
529dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
530dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
531dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
532dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
533dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
534dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
535dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
536dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
537dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
538dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
539dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
54077c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION,
54177c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION_URI,
542dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
543dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
544dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
545c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
546dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
547dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
548dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
549dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
550dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
551dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
552dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
553dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
554dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
555dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
556dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
557dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
558dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
559dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
560dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
561dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
562dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
563dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
564dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
565dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
566dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
567dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
568dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
569dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
570dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
571dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
572dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
573dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
574dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
575dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
576dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
577dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
578dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
579dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
580dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
581dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
587dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
588dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
589dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testLiveFoldersProjection() {
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "live_folders/contacts"),
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                LiveFolders._ID,
599dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                LiveFolders.NAME,
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
613778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
614778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
6183cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
6193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
6203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
6223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
6233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
6243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
6253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
6263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
6273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
6283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
6293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
6303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
6313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
6323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
6333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
6343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
6353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
6363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
6384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
6393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
6414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
64281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
6433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
6443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6452149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
6462149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
6472149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6482149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long rawContactId = createRawContactWithName();
6492149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
6502149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
6512149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6522149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
6532149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
6542149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6552149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
6562149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
6572149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6582149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6592149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6602149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6612149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
6622149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
6632149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6642149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6652149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6662149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
6672149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
6682149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
6692149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6702149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6712149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6722149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
6732149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
6742149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
6752149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
6762149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
6772149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6782149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6792149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6802149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
6812149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6822149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6832149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6842149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
6852149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6862149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6872149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
6882149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6892149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
690a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
691a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
692a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
693a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
694a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
695a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
696a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
697a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
698a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA);
699a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
700a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
701a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
702a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
703a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
704a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
705a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
706a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
707a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
708a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
709a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
710a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
711a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
712a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
713a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
714a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
715a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
716a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
717a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
718a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
719a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
720a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA);
721a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
722a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
723a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
724a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
725a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
726a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
727a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
728a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
729a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
730a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
731a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
732a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
733a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
734a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
735a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
736a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
737a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
738a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
739a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
740a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
741a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
742a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
743a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
744a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
745a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
746a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
747a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
748a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
749a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
750a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
751a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
752a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
753a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
754a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
755a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
756a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
757a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
758a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
759a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
760a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
761a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
762a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
763a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
764a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
765a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
766a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
767a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
768a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
769a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
770a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
771a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
772a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
773a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
774a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
775a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
776a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
777a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
778a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
779a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
780a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
781a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
782a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
783a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
784a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
785a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
786a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
787a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
788a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
789a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
790a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
791a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
792a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
793a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
794a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
795a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
796a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
797a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
798a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
799a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
800a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
801a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
802a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
803a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
804a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
805a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
806a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
807a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
8094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("John", "Doe");
8104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
8124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
8134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
8144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
8154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
8194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
8214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
8234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
8244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
8254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
8264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
8274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
8294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
8304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
8314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
83281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
8334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
83589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
83689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
83789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
83889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
83989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri1 = insertStructuredName(rawContactId1, "John", "Doe");
84089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
84189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri2 = insertStructuredName(rawContactId2, "Jane", "Doe");
84289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
84389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(dataUri1, account1);
84489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(dataUri2, account2);
84589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
84689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
84789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
84889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
8494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
8507d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
8513cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
8524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
8534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
8544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
8554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
8564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
8574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
8594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
8604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
8624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
8634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
8644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
8684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
8693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
8704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
8724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
8734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
8744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
8754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
8764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
8774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
8784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
8794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
8804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
8814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
88248828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
8834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
8844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
88747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
8885e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
8895e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
8902a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("Chilled", "Guacamole", ACCOUNT_2);
8912a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
8925e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
8934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "tamale");
8944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
8954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
8964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
8975e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
8984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
8994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
9005e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
9014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9025e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1-800-GOOG-411");
9035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
9045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
9055e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "18004664");
9065e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
9075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
9085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "encilada");
9095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
91045d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
91145d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "*");
91245d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
9134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
9144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
915e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
916e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
917e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
918e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
919e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
920e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
921e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
922e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
923e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
9244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
9254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
927e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
928e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
929e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
930e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
931e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
932e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
933e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
934e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
935e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
9364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(lookupUri1, values);
9374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
938892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
939892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // call id should not match to "8004664411"
940e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
941892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
942892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
943892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
944892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
945892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
946892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
947892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
948892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
949892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
950892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
951892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
952892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
953892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
954892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
955892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
956892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
957892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
958892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
959892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
960892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
961892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
962892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
963892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
964892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
965892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
966892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
967892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
968892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
969892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
970892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
971892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
972892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
973892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
974892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
975892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
976892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
977892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot1", "Tamale");
978892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
979892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
980892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
981892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
982892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
983892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
984892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
985892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
986892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
987892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
988892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
989892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
990892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
991892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
992892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
993892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
994892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
995892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
996892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
997892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot2", "Tamale");
998892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
999892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1000892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1001892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1002892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1003892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1004892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1005892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1006892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1007892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1008892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
10094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1011653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1012653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1013653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1014653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1015653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1016653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1017653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1018653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1019653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
10205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri1, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1021653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1022653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1023653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1024653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1025653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1026653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
10275870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1028653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1029653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1030653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1031653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1032653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1033653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1034653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1035653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1036653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1037653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1038653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1039653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
10405870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
104181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1042653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1043653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
10444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
10454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
10474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
10484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
10494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
10504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
10514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
10534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
10544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
10564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertEmail(rawContactId, "meghan@acme.com");
10574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long emailId = ContentUris.parseId(uri);
10584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
10624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
10654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
10664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
10674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
10684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
10714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
10724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
10734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
10744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
107548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
10764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
10774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10795e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
10804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Hot", "Tamale");
10814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
10824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10835e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
10844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
10864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
10874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
10884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
10914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
109208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
109308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
109408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
109508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
109608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
10974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10995e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
110047fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
11015e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
11025e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
11035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
110447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Hot", "Tamale", ACCOUNT_2);
11055e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
11065e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
11085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
11095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
11105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
11115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
11125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
11135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
11145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
11155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
11175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
11185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1119155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
11205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
11215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11221e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
11235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
11245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
11265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
11275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
11285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11297d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1130c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1131c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1132c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
1133c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1134c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1135c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1136c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1137c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1138c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1139c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1140c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1141c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1142c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1143c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1144c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1145c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v1, v2, v3 });
1146c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1147c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1148c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1149c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1150c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1151c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
1152c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1153c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1154c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1155c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1156c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1157c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1158c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1159c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1160c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1161c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1162c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1163c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1164c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
11657d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
11667d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
11677d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
11687d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
11697d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId1 = createRawContact(ACCOUNT_1);
11707d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
11717d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId2 = createRawContact(ACCOUNT_2);
11727d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
11737d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
11747d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
11757d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
11767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
11777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
11807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_1.type)
11817d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11827d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
11837d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
11867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_2.type)
11877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
11897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
11917d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
11937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2 });
11957d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11977d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
11987d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
12007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
12017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
120246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
120346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
120446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId1 = createRawContact();
12054928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
12064928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
120746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId2 = createRawContact();
12084928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
12094928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
12104928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
12114928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
121246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
121346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
121446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
121546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
121646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
121746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
121846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
121946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
122046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
122146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
122246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
122346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
122446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
122546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
122646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
122746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
122846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
122946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
123046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
123146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
123246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
123346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
123446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
123546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
123646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
123746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
12384928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
123946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
124046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // account3@email.com should be the first. account2@email.com should also be promoted as
124146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // it has same contact id.
124246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
124346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
124446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
124546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1246f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1247f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1248f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1249f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1250f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
1251f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long rawContactId1 = createRawContact();
1252f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1253f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1254f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1255f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1256f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1257f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1258f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1259f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1260f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1261f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1262f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1263f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1264f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1265f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1266f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1267f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1268f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1269f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1270f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1271f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1272f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1273f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1274f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1275f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1276f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1277f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1278f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1279f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1280f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1281f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1282f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1283f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1284f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1285f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1286f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1287f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1288f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1289f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1290f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1291f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1292f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1293f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1294f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1295f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1296f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1297f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1298f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1299f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1300f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1301f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1302f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1303f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1304f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1305f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1306f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1307f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1308f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1309f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1310f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
13114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
13124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Alice", "Nextore");
13134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
13144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
13154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
13174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
13194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
13204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
13214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
13224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
13234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
13244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
132548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
132648828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
13274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
13314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1333aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1334d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
13354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
13364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
13384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
13394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
13424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1344aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1345aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
134682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1347aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
1348ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
1349ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
1350ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
13514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1353a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
13544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
135548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1356aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1357d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1358aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
135948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
136048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
136148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
136248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
13633b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
13643b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
13657ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, nameValues);
136648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
136748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
136882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
136948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1370ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
1371ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
13724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
137348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
13743b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
137548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1376a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
13773b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
13783b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
1379a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
13807ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13817ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
13827ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
13837ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
13847ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13857ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
13867ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13877ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
13887ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
1389a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1390a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1391a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1392a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
1393a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1394a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1395a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1396a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1397a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1398a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1399a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1400a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1401a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1402a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1403a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1404a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
1405a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1406a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1407a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
1408a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
1409a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
1410a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
1411a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
1412a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1413a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
1414a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
1415a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1416a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1417a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1418a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
1419a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1420a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1421a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1422a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1423a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1424a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1425a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1426a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1427a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1428a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1429a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1430a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
1431a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1432a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1433a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
1434a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
1435a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
1436a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
1437a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1438a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
1439a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
1440a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
14414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
14432f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
14442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
14452f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
14462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
1447ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
14484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
14492f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
14502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
14514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
14522f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
1453d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
14544928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
14554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
14564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
1457aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
1458aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
14594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
14602f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
14612f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
14622f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
14632f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
1464d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
14654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
14664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values4, "Fay", "Veritt", "18004664414",
1467aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
1468d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
14694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
14702f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
14712f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
14722f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
14732f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14742f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
14754928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
14762f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14772f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
14782f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
14792f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
14802f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14812f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Obtain data ID for an email address of the 1st contact.
14822f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final long dataIdEmail1 = getStoredLongValue(Email.CONTENT_URI,
14832f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                Email.ADDRESS + "=?", new String[] { email1},
14842f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                Email._ID);
14852f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14864928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
14872f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
14884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
14892f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14902f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
14912f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
14924928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
14932f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14942f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // With phone-only parameter, the 1st contact shouldn't be returned, since it is only
14952f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // about email, not phone-call.
14962f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
14972f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
14982f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
14994928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
15004928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
15014928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
15024928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
15034928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
15044928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
15054928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
15064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1507ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
15082f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
15094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
15104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1511ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
15124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
15134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
15154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
1516aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
1517aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
15184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
15204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
1521aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
1522aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
15234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1524ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
15254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
15264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
15274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
15284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
15294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1531ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
15324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
15334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
15344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
15354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1537ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
15384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
15394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
15404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
15423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
154324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRequiresReadPermission() {
154424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
154524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
154624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
154724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
154824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Queries for the profile should fail.
154924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
155024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
155124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieving profile contact.
155224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
155324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI, null, null, null, Contacts._ID);
155424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile without READ_PROFILE access should fail.");
155524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
155624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
155724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
155824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
155924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
156024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
156124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
156224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
156324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
156424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
156524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, Contacts._ID);
156624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile data without READ_PROFILE access should fail.");
156724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
156824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
156924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
157024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
157124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
157224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
157324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
157424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
157524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
157624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon()
157724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("entities").build(), null, null, null, Contacts._ID);
157824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile entities without READ_PROFILE access should fail.");
157924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
158024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
158124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
158224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
158324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
158424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
158524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
158624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
158724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
158824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
158924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
159024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
159124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
159224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
159324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
159424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
159524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
159624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
159724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, Contacts._ID);
159824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile by contact ID without READ_PROFILE access should fail.");
159924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
160024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
160124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
160224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
160324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
160424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
160524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
160624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
160724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
160824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
160924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
161024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
161124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
161224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
161324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
161424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
161524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    profileRawContactId), null, null, null, RawContacts._ID);
161624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw contact profile without READ_PROFILE access should fail.");
161724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
161824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
161924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
162024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
162124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
162224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
162324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
162424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
162524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
162624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
162724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
162824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
162924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
163024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
163124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
163224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
163324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
163424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
163524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw contact profile without READ_PROFILE access should fail.");
163624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
163724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
163824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
163924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
164024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
164124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
164224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
164324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
164424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
164524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(
164624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
164724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("data").build(), null, null, null, null);
164824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw profile data without READ_PROFILE access should fail.");
164924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
165024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
165124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
165224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
165324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
165424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
165524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
165624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
165724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
165824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(
165924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
166024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("entity").build(), null, null, null, null);
166124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw profile entities without READ_PROFILE access should fail.");
166224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
166324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
166424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
166524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
166624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
166724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
166824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
166924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
167024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
167124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
167224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
167324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
167424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
167524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
167624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
167724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
167824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
167924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
168024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
168124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
168224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
168324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, null);
168424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the data in the profile without READ_PROFILE access should fail.");
168524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
168624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
168724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
168824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
168924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
169024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
169124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
169224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
169324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
169424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
169524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
169624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
169724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
169824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
169924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
170024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
170124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, null);
170224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the data in the profile without READ_PROFILE access should fail.");
170324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
170424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
170524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
170624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
170724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
170824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
170924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
171024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
171124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
171224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
171324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
171424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
171524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
171624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
171724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
171824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
171924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
172024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
172124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
172224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
172324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
172424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
172524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
172624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
172724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
172824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
172924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
173024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
173124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
173224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
173324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
173424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
173524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
17366ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
17376ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
17386ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
17396ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17406ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
17416ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long rawContactId = createRawContactWithName("Domo", "Arigato");
17426ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
17436ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
17446ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
17456ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
17466ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17476ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
17486ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
17496ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
17506ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
17516ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
17526ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
17536ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17546ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
17556ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
17566ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
17576ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
175824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactIncludeProfile() {
175924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
176024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
176124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
176224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
176324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
176424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
176524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
176624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
176724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri contactWithProfilesUri = Contacts.CONTENT_URI.buildUpon()
1768377850d2dfd28eaf1b22273a50cfe066f6667ab9Dave Santoro                .appendQueryParameter(ContactsContract.ALLOW_PROFILE, "1").build();
176924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValuesOrderly(contactWithProfilesUri,
177024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new ContentValues[]{profileValues, nonProfileValues});
177124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(contactWithProfilesUri, profileValues, Contacts._ID, profileContactId);
177224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
177324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
177424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
177524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
177624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
177724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
177824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
177924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
178024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
178124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
178224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
178324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
178424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
178524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
178624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
178724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
178824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
178924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
179024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
179124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
179224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
179324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
179424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
179524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
179624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
179724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
179824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
179924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
180024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
180124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
180224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
180324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
180424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
180524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
180624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
180724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
180824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
180924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
181024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
181124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
181224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
181324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
181424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
181524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
181624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
181724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
181824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
181924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
182024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
182224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
182324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
182424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
182624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
182724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
182924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
183024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
183124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
183224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
183324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
183424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
183524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
183624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
183724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
183824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
183924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
184024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
184124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
184224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
184324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
184424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
184524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
184624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
184724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
184824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
184924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
185024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
185224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
185324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
185524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
185624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
185724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
185824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
186024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
186124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
186224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
186324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
186424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
186524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
186624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
186724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
186824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
186924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
187024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
187124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
187224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
187324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
18740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
187519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
187619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
187719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
187819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
187919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
188019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
188119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
188219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
188319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
188419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
188519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
188619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
188782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
1888aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
1889aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
189082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
1891aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
1892aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
189319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
189419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
189582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
189619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
1897a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
1898a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
189919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
190019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
190119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
190219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
190319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
190482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
19050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
190619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
190719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
190819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
1909a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
191019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
191119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
191219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
191319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
191419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
191582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
19160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
191719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
191819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
191919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
1920a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
192119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
192219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
192319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
192419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
192519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
192689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
192789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
192889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
192989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
193089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
193189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
193289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
193389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
193489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
193589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
193689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
193789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
193889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
19393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
19403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
19413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
19423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
19433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
19443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
19453cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
19463cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
19473cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
19483cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
19493cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
19503cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
19513cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
195294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
19533cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
19543cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
19553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
19563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
19573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
19583cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
19593cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
196073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
19613cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
19623cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
19633cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
196489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
196589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
196689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
196789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
196889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
196989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
197089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
197189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
197289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
197389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
197489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0") ;
197589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
197689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1") ;
197789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
197889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
19794097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
1980d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
19814097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
19824097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
19835ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
19844097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
198517a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
19864097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
19874097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
198867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
198967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        long rawContactId = createRawContact();
199067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
199167c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
199267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
199367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
199467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        insertStructuredName(rawContactId, values);
199517a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
199667c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
199767c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
19984097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
1999d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
20004097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
20014097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
20024097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
20035ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
20044097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
20055ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
20064097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
20074097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
20085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
20095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        final long rawContactId = createRawContact(null);
20105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
20125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
20135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
20145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
20155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
20165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
20175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
20185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
20205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
202155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
202255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
20235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
20245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
20255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
20265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
20275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
20295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
20305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
20325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
203355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
203455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
20355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
20365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
20375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
20385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
20395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
20415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
20425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
20435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
20455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
20465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
20475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
20495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // Only run this test when Chinese collation is supported
20515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
20525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
20535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
20545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
20565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
20585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
20595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
20605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
20625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
20635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
20645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
20655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
20665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
20674cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
20684cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
20695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
20715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
20725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
20745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
20755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
20765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
20775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
20785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
20794cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
20804cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
20815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
20835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
20845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
20855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
20875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
20885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
20895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
20915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
20925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
20945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
20955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
20965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
20975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
20985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
20995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
21005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
21015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
21025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
21035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
21045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
21055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
21065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
21085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
21095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
21115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
21125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
21135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
21145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
21155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
21165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
21175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
21185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
21205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
21215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
21225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
21245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
21255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
21265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
212725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
212825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId1 = createRawContact();
212925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
213025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
213125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId2 = createRawContact();
213225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
213325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
21340c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
21350c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
213625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
213725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
213825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
213925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertStructuredName(rawContactId2, "Potato", "Head");
214025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
214125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
214281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
214325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
214425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
214501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
214601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long rawContactId = createRawContact();
214701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2148a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
214901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
215001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
215101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
215201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
215301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
215401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
215501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
215601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
215701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
215801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
215901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
216001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
216101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2162a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
2163a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2164a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
21655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
216601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
216701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2168a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
2169a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
2170a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
2171a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
2172a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
2173a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2174a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
2175a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
2176a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
2177a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertStructuredName(rawContactId, values);
21785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
21795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
21805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
21825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
21835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
21845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
21855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
21875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
21895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
21905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
21915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
21925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
21935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
21955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
21965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
21975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
21985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
22015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
22025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
22035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
22045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
22055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
22065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
22075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
22095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
22105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
22115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
22125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
22145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
22165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
22185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
22195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
22205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
22235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
22245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
22255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
22265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
22275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
22285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
22295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
22310b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        boolean hasChineseCollator = false;
22320b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        final Locale locale[] = Collator.getAvailableLocales();
22330b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        for (int i = 0; i < locale.length; i++) {
22340b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            if (locale[i].equals(Locale.CHINA)) {
22350b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                hasChineseCollator = true;
22360b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                break;
22370b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            }
22380b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
22390b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
22400b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        if (!hasChineseCollator) {
22410b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
22420b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
22430b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
22445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
22455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
22465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
22475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
22495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
22515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
22535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
22545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
22575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
22585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
22594cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
22604cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
22615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
226201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
226301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
226431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
226531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long rawContactId = createRawContact();
226631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
226731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
226831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
226931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
227031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
227131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
227231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
227331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
227431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
227531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
227631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
227731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
227831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
227931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
228031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
228131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
228231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
228331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
228431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
228531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
228631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
228731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
228831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
228931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
229031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
229131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
229231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
229331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
229431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
229531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
229631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
229731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
229831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
229931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
230031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
230131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
230231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
230331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
230431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
230531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
230631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
230731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
230831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
230931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
231031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
231131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
2312a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
2313a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, filter);
2314a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
2315a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2316a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2317916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
2318916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2319916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2320916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2321916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
2322916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
2323916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2324916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2325916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2326916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
23279c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
2328916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
2329916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2330916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
2331916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
2332916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2333916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2334916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
2335916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
2336916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2337916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2338916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
2339916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2340916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2341916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("acme"));
2342916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2343916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2344916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
23453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "engineer, [acmecorp]");
2346916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2347916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2348916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2349916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
2350916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContact();
2351916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2352916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2353916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
23543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "John", "Doe");
2355916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2356916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2357916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("acme"));
2358916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2359916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2360916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
23613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[acme@corp.com]");
2362916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2363916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2364916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
23653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
23663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
23673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
23683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
23693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
23703716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
23713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
23723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
23733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
23743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
23753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
23763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
23773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
23793716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23803716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
23813716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23823716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
23833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
23853716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
23873716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
23893716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
23903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
23913716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
23923716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
2393916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
2394916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2395916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2396916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2397916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2398916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
2399916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2400916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("inc"));
2401916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2402916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2403916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
240430cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        values.put(SearchSnippetColumns.SNIPPET, "[Incredible]");
2405916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2406916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2407916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
24083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
24093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
24103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
24113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
24123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
24133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
24153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
24163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
24173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
24183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
24203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
24213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("john")),
24223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
24233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
24243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
24263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
24273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
24283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
24293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
24303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
24323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
24333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
24343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
24353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
24373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
24383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
24393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
24413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
24423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
24433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
24443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
24453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
24463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
24473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
24483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
24493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
24513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
24523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
24533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
24543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
24563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("aperture")), emptySnippet);
24573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
24583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
24603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
24613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
24623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
24633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
24643716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
24663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
24673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
24683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
24693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24703716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("860")),
24713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
24723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
24733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
24753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
24763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
24773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
24783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
24793716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24803716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
24813716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
24823716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
24833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
24843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
24853716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
24863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
24873716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
24883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
2489dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
2490dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long rawContactId = createRawContact();
2491dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, "Slinky", "Dog");
2492dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2493dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2494dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2495dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2496dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
2497dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2498dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
2499dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
2500dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2501dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2502dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
2503dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2504dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
2505dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2506dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2507dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
2508dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2509dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
2510dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2511dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2512dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
2513dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
2514dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2515d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
2516d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
2517d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
2518d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
2519d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
2520d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
2521d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
2522d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
2523d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
2524d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
2525d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
2526d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
2527d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
2528d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2529d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
2530d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
2531d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
2532d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
2533c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
2534d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2535d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2536d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
2537d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
2538d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
2539d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
2540d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
2541d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2542d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2543d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
2544c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
2545d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2546d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2547d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
2548d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
254981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
25508c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
25518c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
25528c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
25538c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
2554d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2555d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2556d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
25573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("a", "b");
2558d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2559d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
2560d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
25613cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("c", "d");
2562d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2563d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
2564d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2565d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
25660c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
25670c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2568d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2569d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
2570d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
2571d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2572d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2573d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
25743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("e", "f");
2575d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2576d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
2577d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
25783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("g", "h");
2579d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2580d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
2581d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2582d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
25830c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
25840c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2585d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2586d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
25870c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
2588d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2589d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2590d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
25913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("i", "j");
2592d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2593d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
2594d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
25953cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("k", "l");
2596d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2597d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
2598d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2599d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
26000c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
26010c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2602d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2603d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
26040c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
26050c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2606d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
26073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
2608d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
2609d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2610d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
261182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
26124dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        long rawContactId = createRawContact();
26130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
26140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
26150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
26170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
26180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
26190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
26200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
26210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
26220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
26230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
26240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
26250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
26260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
26270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
26290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
26310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
26330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
26340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
26360a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
26370a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
26380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
26390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
26400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
26410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
26420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26430a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
26440a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
26460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
26470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
26480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
26490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
26500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
26510a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
26520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
26530a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
26550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
26560a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
26570a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
26580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
26590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
26600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
26610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
26620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
26630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26640a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
26650a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
26660a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
26670a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
26680a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26690a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
26700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
26710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
26720a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
26730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
26740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26750a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
26760a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26770a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
26780a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
26790a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
26800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
26810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26820a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
26830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
26840a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
26850a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
26860a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
26874dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
26884dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
268982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
26904dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
26914dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
2692aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2693aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
26944dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
26954dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
2696aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
2697d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
26984dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
26994dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
2700aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
2701aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
27024dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
27034dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
2704aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
2705aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
27064dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
270782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
270882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
27090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
271082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
27114dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
271282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
27134dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
271482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
27154dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
271682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
27174dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
27184dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
2719bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2720bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2721bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2722bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2723bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
272482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
27250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2726bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2727bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
2728bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
272982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
2730bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long rawContactId = createRawContact();
2731bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2732bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2733bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2734bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2735bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2736bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
273782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
273882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
2739bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2740bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2741aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
2742aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
2743aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
2744aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
274582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
2746aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2747aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
274882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
2749bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
275082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
275182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2752bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2753bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
27549705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
27559705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
27569705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
27579705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
27589705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
27599705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
27609705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
27619705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
27629705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
27639705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
27649705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
27659705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
27669705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
27679705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
27689705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
27699705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
27709705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
27719705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
27729705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
27739705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
27749705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
27759705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
27769705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
27779705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
27789705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
27799705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
27809705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
27819705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
27829705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
27839705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
27849705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
27859705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
27869705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
27879705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
27889705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
27899705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
27909705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
27919705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
27929705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
27939705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
27949705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
27959705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
27969705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
27979705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
279882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
27999705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
280082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
2801a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2802a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
2803a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
2804093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
2805093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long rawContactId = createRawContact();
2806093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2807093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2808093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2809093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2810093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2811093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
2812093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
2813093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2814093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
2815093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
2816093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2817093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
2818093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2819093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2820093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2821093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
2822093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
2823093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
2824093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
2825093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2826093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
2827093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
2828093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2829093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2830093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
2831093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
283282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
2833a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long rawContactId = createRawContact();
2834a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2835a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
2836a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
2837a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2838a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2839aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
2840aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
2841aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
2842aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
2843aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
2844aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
2845a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
2846a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
2847a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
284882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
284982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2850bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
28514dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
28524dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
285382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
285482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
28554dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
285682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
285782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
2858a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
285982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
28604dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
28614dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
28624dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
28633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
28643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
28653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
28663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
28673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
28683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
28693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
28703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
28713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
28723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
28733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
28743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
28753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
28763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
28773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
28783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
28793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
28803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
28813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
28823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
28833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
28843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
28853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
28863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
28873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
28883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
28893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
28903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
28913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
28923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
28933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
28943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
28953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
28963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
28973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
28983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
28993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
29023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
29043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
29053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
29063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
29073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
29083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
29093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
29103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
29113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
29123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
29133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
29143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
29173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
29193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
29203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
29213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
29243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
29263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
29273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
29293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
29303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
29313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
29333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
29343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
29353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
29373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
29383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
29393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
29423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
29443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
29453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
29463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
29483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
29493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
29503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
29513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
29533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
29543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
29553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
29573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
29583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
29593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
29623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
29643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
29663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
29673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
29683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
29703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
29716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
29723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
29733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
29743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
29763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
29773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
29783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
29793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
29813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
29823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
29843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
29853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
29863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
29873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
29893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
29903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
29913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
29923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
29943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
29953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
29966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
29973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
29983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
29993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
30006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
30016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
30023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
30036802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
30043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
30063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
30073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
30083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
30093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
30123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
30153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
30163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
30173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
30183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
30203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
30213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
30223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
30233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
30253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
30263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
30273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
30286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
30293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
30313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
30326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
30336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
30343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
30353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
30366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
30373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
30393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
30403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
30423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
30433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
30443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
30453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
30473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
30483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
30503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
30513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
30523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
30533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
30563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemIntoOtherAccount() {
30583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
30593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
30613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(rawContactId, values, mAccountTwo);
30623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Stream insertion was allowed in another account's raw contact.");
30633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
30643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert stream items into account one's raw contact is forbidden.
30653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
30663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
30693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
30703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
30723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
30743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
30763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
30773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
30793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
30803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
30813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
30823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
30833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
30843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
30853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
30863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
30893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
30923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
30933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
30943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
30953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
30963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
30993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
31013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
31023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
31043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
31063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
31073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
31083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
31093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
31103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
31113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
31123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
31133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
31153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
31163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
31173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
31183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
31193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
31203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
31213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
31223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
31233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
31243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
31253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
31263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
31273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
31283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
31303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
31313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
31343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
31363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
31373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
31393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
31403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
31413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
31423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
31433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
31443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
31453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
31463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
31483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
31493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
31503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
31513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
31523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
31553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
31573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
31593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
31603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
31623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
31633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
31643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
31653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
31663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
31673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
31683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
31693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
31703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
31713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
31723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
31733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
31743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
31753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
31773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
31783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
31793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
31803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
31813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
31823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
31833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
31843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
31853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
31863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
31873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
31883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
31903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
31916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
31926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
31933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
31943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
31953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
31966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
31976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
31986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
31996802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
32006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                assertInputStreamContent(expectedPhotoBytes,
32016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        mResolver.openInputStream(Uri.parse(photoUri)));
32026802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
32033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
32043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
32053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
32093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
32113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
32143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
32153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
32163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
32173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
32183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
32193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
32203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
32213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
32243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
32273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
32283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
32293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
32303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
32313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
32323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
32333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
32343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemFromOtherAccount() {
32373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
32383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, mAccount);
32403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
32413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
32423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
32433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
32443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.update(maybeAddAccountQueryParameters(StreamItems.CONTENT_URI, mAccountTwo),
32453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    values, null, null);
32463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to update stream items inserted by another account");
32473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
32483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't update the stream items from another account.
32493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
32533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32546802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
32553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
32583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
32593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
32603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
32613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
32623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
32646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
32653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
32663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
32673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
32683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
32693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
32703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
32713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
32726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
32733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
32746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
32756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
32766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
32776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
32786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
32793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
32823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
32853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
32863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
32873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
32883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
32893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
32916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
32926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
32933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
32943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
32953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
32963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
32973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
32986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
32993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
33006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
33016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
33026802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
33036802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
33046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
33053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemPhotoFromOtherAccount() {
33083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
33093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
33103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, mAccount);
33113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
33123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
33133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, mAccount);
33143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
33153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
33176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
33186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
33193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
33203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                maybeAddAccountQueryParameters(
33213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
33223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
33233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
33243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        mAccountTwo);
33253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
33263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.update(photoUri, photoValues, null, null);
33273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to update stream item photos inserted by another account");
33283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
33293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't update a stream item photo inserted by another account.
33303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
33343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
33363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
33383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
33393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
33403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
33423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
33433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
33443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
33463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
33473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
33483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
33503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
33513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
33523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
33533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
33563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
33583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
33593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
33613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
33623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
33633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
33653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
33663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
33673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
33693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
33703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
33713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
33723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemFromOtherAccount() {
33753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
33763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
33773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), mAccount));
33783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
33793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.delete(
33803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    maybeAddAccountQueryParameters(
33813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
33823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            mAccountTwo), null, null);
33833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to delete stream item inserted by another account");
33843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
33853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't delete a stream item from another account.
33863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
33903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
33923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
33943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
33953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
33963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
33973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
33983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
33993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
34003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
34023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
34033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
34053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
34063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
34073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
34083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
34093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
34103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
34113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
34123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
34133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
34163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
34183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
34193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
34203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
34213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
34226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
34233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
34243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
34253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
34273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
34283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
34303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoFromOtherAccount() {
34333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
34343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
34353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), mAccount));
34363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), mAccount);
34373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
34383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.delete(maybeAddAccountQueryParameters(
34393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    Uri.withAppendedPath(
34403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
34423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    mAccountTwo), null, null);
34433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to delete stream item photo inserted by another account");
34443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
34453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't delete a stream item photo from another account.
34463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
34473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
34503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
34513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
34523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
34533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34556802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
34566802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
34576802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34586802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
34596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
34616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
34626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
34636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
34646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
34656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
34666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
34676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
34696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
34706802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.TEXT, "hacking");
34716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
34726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
34736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
34746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
34756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
34766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
34786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
34806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
34816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
34826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
34836802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
34846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
34856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
34866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
34886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
34896802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
34906802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
34926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
34936802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.TEXT, "finished hacking");
34946802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
34956802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
34966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
34976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
34986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
34996802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
35003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
35013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
35023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
35033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
35043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
35053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
35063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
35093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
35103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
35116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
35126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
35133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
35143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
351682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
3517bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
3518bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
3519bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3520d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact();
35214dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
3522bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3523aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
3524aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3525aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
3526aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3527aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
3528aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3529bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3530af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
353182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
35324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
3533bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3534bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
353582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
353682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
35370265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
3538bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
3539bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3540d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
3541d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
3542d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
3543d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
3544d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
3545d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
3546d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
3547d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3548d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3549d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
3550d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
35518c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
35528c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
35538c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
35548c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
35558c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
35568c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
35578c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
35588c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
35598c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
35608c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
35618c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
35628c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
35638c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
3564d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3565d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3566d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
3567d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
3568d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3569d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3570d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3571d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
3572d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
3573d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
3574d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
3575d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
3576d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
3577d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
3578d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3579d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
35809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
35819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    public void testGroupCreationAfterMembershipInsert() {
3582d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
3583d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
35849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
35859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
35869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3587d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                rawContactId1, groupId, "gsid1");
35889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
35899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
35909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    public void testGroupReuseAfterMembershipInsert() {
3591d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
35929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3593d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
35949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
35959261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
35969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3597d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov                rawContactId1, groupId1, "gsid1");
35989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
35999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
36009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    public void testGroupInsertFailureOnGroupIdConflict() {
3601d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
36029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
36039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
36049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues values = new ContentValues();
3605d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
36069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
36079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
36089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
36099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        try {
36109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana            mResolver.insert(Data.CONTENT_URI, values);
36119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana            fail("the insert was expected to fail, but it succeeded");
36129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        } catch (IllegalArgumentException e) {
36139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana            // this was expected
36149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        }
36159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
36169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
36170be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
36180be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
36190be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
36200be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36210be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
36220be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
36230be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36240be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
36250be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
36260be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36270be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
36280be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
36290be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36300be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
36310be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
36320be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36330be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
36340be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
36350be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36360be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
36370be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
36380be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
36390be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36400be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
36410be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
36420be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
36430be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
36440be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
36450db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
36460db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
36470db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
36480db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
36490db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
36500db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
36510db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
36520db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
36530db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
36540db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
36550db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
36560db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
36570db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
36580db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
36590db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
36600db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
36610db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
36620db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
36630db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
36640db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
36650db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
36660db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
36670db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
36680db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
36690db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
36700db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
36710db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
36720db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
36730db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
36740db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
36750db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
36760db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
3677a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
36789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
36799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
36809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
36819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
36829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
36839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
36843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c0");
36853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
36863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
36873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
36889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
3689226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c1 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c1");
36909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
36919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
36929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
36939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
36949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
3695226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c2 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c2");
36969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
36979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
36989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
36999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
37003cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long c3 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c3");
37019261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
37029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
37039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
37049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
370562318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
370662318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount), null,
370762318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
37089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
37099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
37109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
37116cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
37129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
37139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
37149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
37159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
37169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
37179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
37189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
37199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
37209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
37219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
37229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
37239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
37249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
37259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
37269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
37279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
37289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
37299261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
37306cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
37319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
37329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
37339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
37349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
37359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
37369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
37379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
37389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
37399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
37409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
37419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
37429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
37439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
37449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
37456cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
37469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
37479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
37489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
37499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
37509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
37519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
37529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
37539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
37549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
37559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
37569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
37579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
37589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
37599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
37603cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
37619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
376220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
376320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
3764d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
376520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
376620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
37675ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
376820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
376920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
377020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
377120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
377220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
377320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
377420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
377520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
377620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
377720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
377820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
377920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
378020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
378120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
378220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
378320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
378420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
378520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
378620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
378720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
378820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
378981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
379020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
379120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
379220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
379320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
379420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
379520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
379620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
379720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
379820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
379920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
380020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
380120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
380220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
380320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
380420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
380520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
380620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
380720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
380820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
380920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
38105ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
381120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
381281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
381370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
381420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
381520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
38165ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
381720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
381820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
38195ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
382033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
382181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
382233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
382320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
382489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
382589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
382689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
382789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
382889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
382989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
383089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
383189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
383289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
383389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
383489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
383589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
383689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
383789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
383889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
383989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
384089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
384189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
384289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
3843373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
3844e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId = createRawContact(mAccount);
38455ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
384633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
38474dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
384882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
3849aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
3850aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3851a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3852a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
385333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
385433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
385582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
38564dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
385733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
385833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
385933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
38605870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
386181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
386233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
3863e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
386433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
386533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
386633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
386733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
386882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
38694dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
3870a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
387181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
3872a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
3873a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
3874a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
3875e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId1 = createRawContactWithName(mAccount);
3876e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId2 = createRawContactWithName(mAccount);
387747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
387847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
3879a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
3880a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
3881a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
3882a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
3883e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
3884a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
3885a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
3886a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
388720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
38881fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
3889e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    public void testRawContactDeletionWithAccounts() {
3890e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        long rawContactId = createRawContact(mAccount);
3891e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
3892e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
3893e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
389482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
3895aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
3896aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3897e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
3898e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
389982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
3900e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
3901e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
3902e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
3903e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
3904e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
3905e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
3906e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
3907e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
3908e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        mResolver.delete(deleteWithWrongAccountUri, null, null);
3909e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
39105870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
3911e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
3912e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
3913e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
3914e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
3915e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
3916e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
3917e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
3918e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        mResolver.delete(deleteWithCorrectAccountUri, null, null);
3919e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
39205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
3921e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
3922e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
3923627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
392470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
392570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
392670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        long rawContactId3 = createRawContactWithName("James", "Sullivan");
392770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
3928627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
3929743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
393070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
393170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
3932bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
3933743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
3934743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
3935dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
3936dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
393770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
3938743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
3939743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
3940743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId2 = createRawContact(mAccountTwo);
3941743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
3942743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
3943743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
3944aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
3945aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3946743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
3947bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
3948743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
3949627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
395082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
395170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
395270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
395370d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
395433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
395533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
395633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
3957bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
395833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
395933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
396033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", readOnlyAccount);
396133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
396233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("john", "doe", mAccount);
396333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
396433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
396533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
396633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
396733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
396833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
396933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
397033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
397133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
397233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
397333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
397433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
397533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
397633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
397733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
397833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
397933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
3980bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
398133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
398233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
398333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
398433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
398533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
398633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
398733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
398833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
398933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
399033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
399133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
399233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
399333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
399433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
3995cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
399647fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", ACCOUNT_1);
399747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("John", "Doe", ACCOUNT_2);
3998cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
3999cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4000cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4001cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
4002cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4003cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
4004cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4005cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
4006cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4007cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
4008cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
400973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
401073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
401173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
401273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
401373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri uri = insertStructuredName(rawContactId, "John", "Doe");
401473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
4015e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
401673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
401773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
401873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
401973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
40205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
402173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
402281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
40231fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
40241fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
402561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
4026d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
4027d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
402873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
40291fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
40301fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
40311fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
40321fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
40331fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
403461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
4035c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
403661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
40371fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
40381fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
40391fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
40401fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
404181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
40421fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
404361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
404461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
404581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
40461fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
40471fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
404861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
40491fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
405061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
405161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
405261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
40531fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
405481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
40551fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
40561fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
405761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
40581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
405961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
40601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
406181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
40621fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
40631fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
406461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
40651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
406661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
406761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
406861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
406961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
407061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
407161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
40721fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
407361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
40741fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
40751fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
40761fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
40771fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
40781fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
40791fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
40801fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
408161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
408261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
40831fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
408461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
40851fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
408661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
408761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
408861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
408961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
40905870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
409161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
409281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
409361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
409461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
40951fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
40964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
40979fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
40989fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
40999fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
41009fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41019fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
41029fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41039fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
41049fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
41059fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
41069fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41079fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
41089fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
41099fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
41109fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41119fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
41129fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
41139fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
41149fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41159fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
41169fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
41179fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
41189fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
41199fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
41209fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
41219fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
41229fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
412360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
412460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
412560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
412660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
412760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
412860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
412960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
413060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
413160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
413260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
413360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
413460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
413560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
413660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
413760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
413860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
413960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
414060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
414160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
414260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
414360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
414460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
414560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
414660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
414760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
414860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
4149074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
4150074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
4151074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
4152074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
4153074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
4154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
4156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
4157f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
4158f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
4159074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
41603d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
41613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
4162f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
4163074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
4164074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
4165ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
4166e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov        long rawContactId = createRawContact();
4167f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4168f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4169f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
4170f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
4171f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
4172e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
4173f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.DISPLAY_PHOTO),
4174f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.THUMBNAIL),
4176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
4177ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
4178ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
4179ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    private static void assertInputStreamContent(byte[] expected, InputStream is)
4180ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            throws IOException {
4181ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        try {
4182ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            byte[] observed = new byte[expected.length];
4183ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            int count = is.read(observed);
4184ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(expected.length, count);
4185ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(-1, is.read());
4186ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            MoreAsserts.assertEquals(expected, observed);
4187ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        } finally {
4188ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            is.close();
4189ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        }
4190e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov    }
4191e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
4192732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
4193732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId1 = createRawContact(new Account("a", "a"));
4194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
4195732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
4196732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4197732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId2 = createRawContact(new Account("b", "b"));
4198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
4199732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
4200732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4201732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
4202732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4203732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4204732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
4205732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
4206f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4207f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
4208f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
4209f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
4210f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
4211732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
4212f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
4213732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4214732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
4215732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4216732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4217732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
4218732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
4219732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
4220732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4221732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
4222732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4223732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
4224732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
4225732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
4226732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4227732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
4228732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
4229732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
4230732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
42318e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
42328e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
42338e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
42348e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
42358e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
42368e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
42378e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
42388e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
42398e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
42408e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
42418e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
42428e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
42438e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
42448e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
42458e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
42468e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
4247155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
42488e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
42498e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
42508e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
42518e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
425281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
42538e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
4254f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
42558e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
42568e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
42578e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
42584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
42597d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
42607d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
42617d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
42627d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
42637d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
42647d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
42657d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
42667d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
42677d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
42687d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
42697d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
42707d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
42717d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
42727d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
42737d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
42747d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
42757d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
42767d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
42777d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
42787d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
42797d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
42807d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
42817d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
42827d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
42837d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
42847d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
42857d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
42864e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
42877d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
42884e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
4289f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
42900265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
42917d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
42927d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
4293f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
4294f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4295f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4296f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4297f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
4298f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
4299f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4300f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4301f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4302f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4303f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4304f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4305f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
4306f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4307f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4308f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
4309f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4310f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
4311f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
4312f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4313f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4314f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4315f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4316f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4317f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4318f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
4319f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4320f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4321f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
4322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4323f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
4324f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
4325f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
4326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4327f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4328f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4329f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4330f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4331f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4332f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
4333f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4334f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4335f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
4336f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4337f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4338f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4339f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4340f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4341f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4342f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4343f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
4344f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4345f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4346f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4347f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4348f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
4349f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4350f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4351f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4352f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4353f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4354f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4355f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4356f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4357f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
4358f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4359f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4360f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4361f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
4362f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4363f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
4364f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
4365f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4366f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4367f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4368f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4369f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
4370f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4371f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4372f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4373f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
4374f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4375f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
4376f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
4377f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
4378f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4379f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4380f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
4381f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4382f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4383f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4384f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
4385f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
4386f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
4387f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4388f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4389f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4390f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4391f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
4392f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4393f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4394f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4395f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
4396f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4397f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
4398f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
4399f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4400f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
4401f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
4402f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4403f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
4404f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4405f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
4406f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4407f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4408f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4409f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testWriteNewPhotoToAssetFile() throws IOException {
4410f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4411f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4412f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4413f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
4414f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
4415f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4416f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
4417f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
4418f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4419f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4420f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        OutputStream os = mResolver.openOutputStream(writeablePhotoUri, "rw");
4421f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
4422f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.write(originalPhoto);
4423f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
4424f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.close();
4425f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
4426f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4427f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
4428f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4429f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4430f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
4431f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4432f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4433f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4434f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
4435f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
4436f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4437f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
4438f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4439f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
4440f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4441f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4442f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
4443f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
4444f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4445f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4446f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws IOException {
4447f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4448f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4449f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4450f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
4451f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
4452f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
4453f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4454f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4455f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
4456f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
4457f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4458f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
4459f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
4460f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4461f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4462f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        OutputStream os = mResolver.openOutputStream(writeablePhotoUri, "rw");
4463f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
4464f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.write(originalPhoto);
4465f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
4466f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.close();
4467f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
4468f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4469f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
4470f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
4471f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4472f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
4473f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4474f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
4475f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
4476f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4477f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4478f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4479f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
4480f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
4481f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4482f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
4483f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
4484f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4485f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4486f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4487f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
4488f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
4489f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
4490f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
4491f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
4492f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4493f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4494f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
4495f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
4496f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4497f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
4498f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
4499f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4500f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
4501f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId1 = createRawContactWithName();
4502f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
4503f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
4504f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
4505f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
4506f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4507f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4508f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId2 = createRawContactWithName();
4509f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
4510f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
4511f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
4512f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
4513f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4514f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4515f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
4516f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
4517f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
4518f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
4519f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
4520f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
4521f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
4522f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
4523f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
4524f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4525f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4526f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
4527f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
4528f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId3 = createRawContactWithName();
4529f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
4530f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
4531f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
4532f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
4533f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
4534f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
4535f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
4536f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
4537f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
4538f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4539f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
4540f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
4541f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
4542f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
4543f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4544f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
4545f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
4546f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4547f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
4548f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4549f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
4550f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
4551f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
4552f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4553f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4554f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
4555f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
4556f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
4557f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4558f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
4559f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4560f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
4561f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
4562f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
4563f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4564f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4565f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
4566f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
4567f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4568f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4569f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
4570f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4571f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4572f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4573f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4574f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
4575f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4576f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
4577f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
4578f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4579f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
4580f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
4581f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
4582f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
4583f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4584f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
4585f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
4586f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
4587f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
4588f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
4589f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
4590f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4591f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
4592f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
4593f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4594f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4595f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
45964e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
45974e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId1 = createRawContactWithName();
45984e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
45994e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId2 = createRawContactWithName();
46004e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
460147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
460247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
46034e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46044e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
46054e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
46064e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
46074e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46084e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
46094e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
46104e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46114e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
46124e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46134e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
46144e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
46154e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
46164e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46174e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
46184e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
46194e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46204e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
46214e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
46224e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
46234e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46244e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
46254e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
46264e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46274e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
46284e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
46294e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
46304e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
46314e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
46326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
46336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId1 = createRawContact(new Account("a", "a"));
46346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
46356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
46366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId2 = createRawContact(new Account("b", "b"));
46386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
46396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
46406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
46426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
46436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
46446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
46456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
46466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
46476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
46486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
46496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
46516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
46526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
46536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
46546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
46556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
46566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
46576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
46586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
46596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
46606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
46616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
46636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
46646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
46656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
46666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
46676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
46686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
46696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
46706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
46726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
46736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
46746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
46756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
46766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
46776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
46786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
46806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
46816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
46826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
46836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
46846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
46856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
46866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
46876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
46896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
46906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
46916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
46926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
46936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
46946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
46956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
46966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
46976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
46986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
46996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
47016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
47026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
47036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
47046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
47056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
47086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
47096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
47106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
47116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
47136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
47146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
47156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
47166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
47176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
47206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
47216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
47226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
47236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
47246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
47256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
47266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
47276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
47306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
47316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
47326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
47336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
47346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId = createRawContact(new Account("a", "a"));
47356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
47366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
47386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
47396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
47406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
47416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
47446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
47456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
47476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
47486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
47496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
47506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
47526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
47536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
47546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
47556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
47576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
47586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
47596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
47606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
47616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
47626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
47656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
47666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
47676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
47686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
47696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
47706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
47736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
47746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
47776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
47786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
47816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
47826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
47856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
47866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
47876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47881b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    public void testLiveFolders() {
47891b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId1 = createRawContactWithName("James", "Sullivan");
47901b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        insertPhoneNumber(rawContactId1, "5234567890");
47911b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
47921b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
47931b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Mike", "Wazowski");
47941b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
47951b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        storeValue(Contacts.CONTENT_URI, contactId2, Contacts.STARRED, "1");
47961b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
47971b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId3 = createRawContactWithName("Randall", "Boggs");
47981b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId3 = queryContactId(rawContactId3);
47991b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long groupId = createGroup(NO_ACCOUNT, "src1", "VIP");
48001b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        insertGroupMembership(rawContactId3, groupId);
48011b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
48021b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
48031b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
48041b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts"),
48051b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId1, "James Sullivan",
48061b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId2, "Mike Wazowski",
48071b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId3, "Randall Boggs");
48081b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
48091b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
48101b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
48111b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts_with_phones"),
48121b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId1, "James Sullivan");
48131b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
48141b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
48151b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
48161b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/favorites"),
48171b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId2, "Mike Wazowski");
48181b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
48191b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
48201b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
48211b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts"), Uri.encode("VIP")),
48221b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId3, "Randall Boggs");
48231b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    }
48241b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
48251b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    private void assertLiveFolderContents(Uri uri, Object... expected) {
48261b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        Cursor c = mResolver.query(uri, new String[]{LiveFolders._ID, LiveFolders.NAME},
48271b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                null, null, LiveFolders._ID);
48281b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertEquals(expected.length/2, c.getCount());
48291b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        for (int i = 0; i < expected.length/2; i++) {
48301b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertTrue(c.moveToNext());
48311b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertEquals(((Long)expected[i * 2]).longValue(), c.getLong(0));
48321b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertEquals(expected[i * 2 + 1], c.getString(1));
48331b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        }
48341b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        c.close();
48351b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    }
48361b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
4837ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
4838ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
4839ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
4840ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4841ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContact();
4842ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("James", "Sullivan");
4843ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("The Abominable", "Snowman");
4844ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mike", "Wazowski");
4845ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("randall", "boggs");
4846ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Boo", null);
4847ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mary", null);
4848ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Roz", null);
4849ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4850ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
4851ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
4852ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_PRIMARY + " COLLATE LOCALIZED");
4853ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4854ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, null, "B", "J", "M", "R", "T");
4855ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
4856ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
4857ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4858ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
4859ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
4860ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
4861ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4862ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", null);
4863ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
4864ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
4865ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
4866ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4867ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
4868ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
4869ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
4870ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
4871ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
4872ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4873ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
4874ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
4875ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
4876ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
4877ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
4878ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4879f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
4880f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
4881f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
4882f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
4883f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
4884f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
4885f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
4886f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
4887f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
4888f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
4889f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
4890f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
4891f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
4892f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
4893f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
4894f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
4895f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
4896f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
4897f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
4898f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
4899f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
4900f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
4901f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
4902f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
4903f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
4904f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
4905f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
4906f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
4907f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
49085fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
49095fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
49105fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
49115fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
49125fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
49135fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
49145fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
49155fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
49165fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
49175fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
49185fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
49195fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
49205fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
4921f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
4922f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
4923e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
4924e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
4925e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
4926e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
4927e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
4928e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
4929e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
4930e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
4931e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
4932e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
4933e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
4934e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
4935e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
4936e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
4937e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
4938e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
4939e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
4940e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
4941e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
4942e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
4943e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
4944e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri insertUri = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, blue);
4945e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
4946e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
4947e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
4948e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
4949e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
4950e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
4951e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
4952e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
49533826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
49543826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
49553826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
49563826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
49573826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
49583826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        long rawContactId = createRawContact();
49593826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
49603826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
49613826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
49623826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
49633826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
49643826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
49653826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
49663826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
4967bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{ACCOUNT_1});
49683826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{ACCOUNT_1});
49693826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
4970bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
49713826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
49723826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
49733826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
49743826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
49753826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
497609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
497709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
497809c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
497909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
49803826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
498109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
498209c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
498309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
4984b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
4985743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
4986b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
4987b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
4988b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
4989b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
4990b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
4991b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
4992b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
4993b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
4994b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
4995b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
4996b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
4997b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
499842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
499942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
500042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
500142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
500242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
500342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
500442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
500542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
500642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
500742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
500842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
500942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
501042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
501142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
501242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
501342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
501442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
501542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
501642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
501742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
501842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
501942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
502042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
502142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
502242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
502342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId1 = createRawContact(mAccount, RawContacts.SOURCE_ID, "4:12");
502442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId1, "John", "Doe");
502542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
502642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId2 = createRawContact(mAccount, RawContacts.SOURCE_ID, "3:4%121");
502742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId2, "Jane", "Doh");
502842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
502942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
503042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
503142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
503242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
503342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
503442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
503542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
503642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
503742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
503842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
503942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
504042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
504142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
504242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
504342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
504442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
504542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
504642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
504742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
504842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
504942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
505042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
505142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
505242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
505342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
505442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
505542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
505642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
505742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
505842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
505942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
506042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
506142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
506242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
506342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
506442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
506542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
506642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
506742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
506842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
506942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
507042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
507142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
507242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
507342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
507442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
507542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
507642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
507742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
507842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
507942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
508024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
508124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
508224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
508324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
508424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
508524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
508624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
508724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
508824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
508924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
509042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
509142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
509242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
509342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
509442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
509542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
509642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
509742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
509842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
509942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
510042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
510142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
510242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
510342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
510442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
510542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
510642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
510742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
510842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
510942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
511042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
511142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
511242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
511342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
511442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
511542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
511642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
511724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
511824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
511924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
512042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
512142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
512242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
512342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
512442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
512542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
512642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
512742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
512842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
512942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
513042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
513142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
513242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
513342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
513442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
5135dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
5136dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
5137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
5139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
5140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5141dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccountTwo);
5142dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(null);
5143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5144dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5145dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5146dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5147dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5148dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5149dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5150dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5151dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5152dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5153dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5154dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
5155dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5156dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5157dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
5158dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
5159dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5160dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5161dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5162dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5163dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5164dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5165dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
5166dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5167dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5168dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount);
5169dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo);
5170dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
5171dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null);
5172dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5173dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5174dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5175dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5176dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
5177dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5178dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
5179dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5180dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5181dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5182dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5183dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5184dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
5185dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
5186dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
5187dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
5188dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
5189dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
5190dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
5191dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5192dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount, RawContacts.STARRED, "1");
5193dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo, RawContacts.STARRED, "1");
5194dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
5195dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null, RawContacts.STARRED, "1");
5196dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r7 = createRawContact(null);
5197dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5198dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5199dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5200dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5201dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5202dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5203dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
5204dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5205dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5206dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5207dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5208dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
5209dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
5210dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
5211dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
5212dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5213dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5214dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5215dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5216dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5217dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5218dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5219dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5220dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5221dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5222dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5223dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5224dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5225dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5226dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5227dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
5228dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
5229dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
5230dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5231dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5232dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5233dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5234dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5235dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5236dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5237dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5238dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5239dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5240dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5241dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
5242dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5243dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5244dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5245dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5246dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5247dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
5248dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5249dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5250dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5251dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5252dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5253dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5254dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5255dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
5256dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
5257dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
5258dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
5259dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5260dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5261dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
5262dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5263dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
5264dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
5265dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
5266dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
5267dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5268dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
5269dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5270dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5271dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5272dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5273dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5274dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5275dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5276dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5277dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5278dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5279dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5280dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5281dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5282dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
5283dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5284dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5285dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5286dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5287dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5288dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
5289dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
5290dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
5291dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
5292dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
5293dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5294dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5295dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5296dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5297dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5298dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5299dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5300dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5301dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5302dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5303dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5304dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5305dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
5306dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5307dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5308dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5309dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5310e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
5311dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
5312dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5313dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
5314dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
5315dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
5316dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
5317dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
5318dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5319dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5320dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5321dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5322dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5323dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5324dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5325dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5326dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5327dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5328dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5329dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5330dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
5331dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5332dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5333dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5334dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5335dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5336dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
5337dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5338dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
5339dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
5340dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
5341dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5342dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5343dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
5344dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5345dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5346dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5347dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5348dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5349dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
5350dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5351dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
5352dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
5353dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
5354dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
5355dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5356dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5357dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5358dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5359dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5360dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5361dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5362dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5363dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5364dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5365dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5366dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5367dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5368dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5369dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
5370dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
5371dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
5372dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5373dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5374dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5375dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
5376dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5377dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5378dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5379dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
5380dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
5381dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
5382dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5383dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5384dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5385dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5386dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
5387dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5388dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5389dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
5390dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5391dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5392dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5393dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5394dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5395dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5396dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
5397dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
5398dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
5399dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5400dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5401dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5402dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5403dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5404dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5405dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
540697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
540797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
540897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
540997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
541097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
541197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
541297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
541397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
541497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
541597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
541697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
541797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
541897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
541997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
542097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
542197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
542297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
542397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
542497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
542597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
542697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
542797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
542897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
542997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
543097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
543197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
543297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
543397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
543497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
543597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
543697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
543797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
543897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
543997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
544097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
544197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId1 = createRawContact();
544297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
544397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
544497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
544597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId2 = createRawContact();
544697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
544797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
544897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
544997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
545097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
545197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
545297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
545397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
545497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
545597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
545697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
545797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
545897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
545997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
546097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
546197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
54627a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
54637a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
54647a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
54657a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
54667a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
54677a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
546817a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
54697a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
54707a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
54717a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
54727a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
54737a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
54747a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
54757a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
54767a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
54777a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
54787a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
54797a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
54807a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
54817a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
54827a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
54837a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
54847a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
54857a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
54867a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
54877a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
54887a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
548955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
54907a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
54917a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
54927a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
54937a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
54947a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
54957a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
54967a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
54977a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
54987a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
54997a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
55007a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
5501dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
5502dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = mResolver.query(maybeAddAccountQueryParameters(Data.CONTENT_URI, account),
5503dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
5504dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
5505dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
5506dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
5507dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5508dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
550942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
551042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
5511bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
551242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
551342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
5514bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
5515bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
5516bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
5517bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
5518bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
5519bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
5520bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
552142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
5522bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
5523bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
552442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
552542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
552642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
552742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
552842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
552942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
5530f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
5531f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
5532f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
5533f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5534f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
55354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
55364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
5537aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
553824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
553924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
554024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
554124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
554224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
554324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
554424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
554548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
554624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
554748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
554848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
554948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
555048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
5551aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
555248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
5553aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
555448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        insertStructuredName(rawContactId, firstName, givenName);
555548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
555648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
555748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
555824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
555924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
556024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
556124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
556224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
556324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        insertStructuredName(rawContactId, firstName, givenName);
556424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
556524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
556624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
556748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
5568aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
556924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
557024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
557124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
557224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
557324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
557424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
557524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
55764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
55774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
55784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
55794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
558024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
558124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
558224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
558324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
558424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
55854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
55864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
55874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
55884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
5589f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov        insertPhoneNumber(rawContactId, phoneNumber);
5590f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov        insertEmail(rawContactId, email);
55914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
5592aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
5593aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                chatMode);
55944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
55954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
55964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
55974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
559824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
559948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
56004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
56014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
560224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
560324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
560424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
560524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
560624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
560724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
560824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
560924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
561024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
561124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
561224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
561324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
561424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
561524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
561624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
561724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
561824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
561924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
562024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
562124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
562224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
562324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
562424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
562524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
562624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
562724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
562824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
562924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
56304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
56314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
56324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
56334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
56344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
56354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
56364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
56374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
56384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
56394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
56404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
56414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
56424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
56434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
56444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
56454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
56464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
56474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
56484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
56494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
56504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
56514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
56524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
56534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
56544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
56554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
56564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
56574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
56584928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
56594928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
56604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
56614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
56624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
56634928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
56644928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
56654928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
56664928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
56674928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendPath(String.valueOf(dataId))
56684928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
56694928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .build();
56704928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertNotSame(0, mResolver.update(feedbackUri, new ContentValues(), null, null));
56714928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
56724928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
56734928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
56744928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
5675d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
5676d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5677