ContactsProvider2Test.java revision f1efadb1255fd75305b59802f736905b9d66e449
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
1945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawaimport com.android.common.contacts.DataUsageStatUpdater;
20d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport com.android.internal.util.ArrayUtils;
21dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
22f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawaimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
23b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
24f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport com.android.providers.contacts.tests.R;
2524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport com.google.android.collect.Lists;
26d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wongimport android.accounts.Account;
28d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderOperation;
29d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderResult;
30d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentUris;
31d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentValues;
329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.content.Entity;
3333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.content.EntityIterator;
3442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport android.content.res.AssetFileDescriptor;
35d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.database.Cursor;
36f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawaimport android.database.sqlite.SQLiteDatabase;
37d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.net.Uri;
38c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract;
39d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
40dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
41dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
42dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
43dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
44dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
45dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
46dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
47dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
48ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikovimport android.provider.ContactsContract.ContactCounts;
49c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.provider.ContactsContract.Data;
5146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawaimport android.provider.ContactsContract.DataUsageFeedback;
52dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.Directory;
535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
54f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.DisplayPhoto;
557a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.ContactsContract.Groups;
574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
5924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
6009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
6133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6262318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
63916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikovimport android.provider.ContactsContract.SearchSnippetColumns;
6489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
6582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
67f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
68dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.LiveFolders;
69dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
707d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
71d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
72f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
73d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
7442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
7542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
76ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringertimport java.io.InputStream;
77f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
84d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
85d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
86d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
87d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
88d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
898920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens * adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
9028f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millar *         com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
91d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
92d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
93d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
94d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
95d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
9647fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_1 = new Account("account_name_1", "account_type_1");
9747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_2 = new Account("account_name_2", "account_type_2");
9847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
99dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
100dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
101dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
102dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
103dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
104dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
105dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
106dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
107dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
108dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
109dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
110dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
111dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
112dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
113dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
114f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1153d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1163d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
117dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
118dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
119dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
12024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
121dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
122dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
123dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
124dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
125dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
126dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
127dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
128dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
129dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
133dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
134dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
135dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
136dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
137dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
138dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
139dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
140dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
142dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
143dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
144dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
147dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
148dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
149f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1503d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1513d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
152dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
153dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
154dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
15524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
156dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
157dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
158dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
159dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
160dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
161dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
162dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
163dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
164dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
165dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
16630cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
167dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
168dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
169dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
170dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
171dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
172dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
173dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
174dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
175dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
176dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
177dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
17824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
179dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
180dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
181dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
182dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
183dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
184dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
185dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
186dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
187dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
188dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
189dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
190dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
191dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
192dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
193dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
194dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
195dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
196dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
197dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
198dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
199dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
200dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
201dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
202dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
203dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
204dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
205dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
206dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
207dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
208dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
209dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
210dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
211dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
212dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
213dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
214dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
215dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
216dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
217dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
218dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
219dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
220dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
221dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
222dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
223dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
224dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
225dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
226dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
227dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
228dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
229dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
230dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
231dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
232dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
233dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
234dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
235dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
236dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
237dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
238dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
239dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
240dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
241dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
242dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
243dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
24424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
245dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
246dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
251dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
252dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
253dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
254dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
255dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
257dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
258f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2593d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2603d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
261dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
264dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
265cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
267dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
268dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
269dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
272dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
273dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
274dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
278dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
283dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
284dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
288dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
295dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
298dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
299dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
309dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
310dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
311dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
312dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
31324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
326dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
327f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3283d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3293d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
330cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
345a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
346a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
347a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
348a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
349a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
350a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
351a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
352a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
353a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
354a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
355a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
356a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
357a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
358a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
359a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
360a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
361a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
362a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
363a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
364a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
365a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
366a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
367a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
368a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
380a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
381a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
383a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
385a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
386a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
387a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
388a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
389a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
390a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
391a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
392a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
393a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
394a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
395a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
396a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
397a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
398a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
399a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
400a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
402a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
403a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
404a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
405a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
406a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
407a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
408a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
409f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4113d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
412a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
413a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
41424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
415a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
416a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
417cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
418a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
419a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
420a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
421a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
422a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
423a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
424a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
425a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
426a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
427a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
428a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
445dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
44624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
449dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
450dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
451dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
460dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
461dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
462dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
463dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
466dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
470dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
471dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
472dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
482dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
483dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
484dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
485dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
4863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
4873d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
488dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
489dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
490dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
491dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
492dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
493dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
4942530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
495dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
496dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
497dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
498dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
499dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
500dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
501dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
502dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
503dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
504dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
505dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
506dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
507dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
508dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
509dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
510dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
511dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
512dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
51377c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION,
51477c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION_URI,
515dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
516dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
517dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
518c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
519dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
520dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
521dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
522dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
523dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
524dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
525dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
526dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
527dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
528dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
529dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
530dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
531dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
532dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
533dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
534dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
535dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
536dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
537dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
538dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
539dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
540dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
54177c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION,
54277c0766a8738feb39f1066a7f3106fef71dd295dDaniel Lehmann                Groups.ACTION_URI,
543dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
544dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
545dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
546c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
547dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
548dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
549dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
550dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
551dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
552dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
553dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
554dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
555dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
556dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
557dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
558dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
559dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
560dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
561dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
562dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
563dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
564dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
565dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
566dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
567dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
568dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
569dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
570dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
571dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
572dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
573dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
574dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
575dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
576dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
577dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
578dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
579dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
580dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
581dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
587dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
588dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
589dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testLiveFoldersProjection() {
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "live_folders/contacts"),
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
599dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                LiveFolders._ID,
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                LiveFolders.NAME,
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
614778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
615778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
618dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
6193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
6203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
6213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
6233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
6243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
6253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
6263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
6273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
6283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
6293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
6303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
6313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
6323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
6333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
6343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
6353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
6363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
6373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
6394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
6403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
6424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
64381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
6443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
6453cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6462149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
6472149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
6482149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6492149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long rawContactId = createRawContactWithName();
6502149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
6512149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
6522149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6532149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
6542149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
6552149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6562149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
6572149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
6582149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6592149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6602149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6612149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6622149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
6632149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
6642149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6652149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6662149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6672149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
6682149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
6692149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
6702149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6712149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6722149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6732149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
6742149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
6752149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
6762149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
6772149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
6782149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6792149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6802149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6812149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
6822149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6832149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6842149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6852149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
6862149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6872149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6882149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
6892149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6902149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
691a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
692a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
693a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
694a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
695a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
696a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
697a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
698a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
699a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA);
700a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
701a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
702a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
703a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
704a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
705a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
706a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
707a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
708a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
709a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
710a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
711a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
712a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
713a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
714a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
715a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
716a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
717a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
718a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
719a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
720a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
721a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA);
722a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
723a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
724a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
725a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
726a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
727a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
728a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
729a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
730a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
731a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
732a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
733a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
734a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
735a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
736a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
737a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
738a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
739a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
740a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
741a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
742a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
743a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
744a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
745a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
746a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
747a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
748a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
749a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
750a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
751a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
752a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
753a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
754a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
755a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
756a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
757a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
758a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
759a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
760a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
761a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
762a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
763a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
764a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
765a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
766a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
767a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
768a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
769a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
770a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
771a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
772a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
773a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
774a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
775a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
776a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
777a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
778a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
779a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
780a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
781a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
782a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
783a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
784a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
785a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
786a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
787a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
788a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
789a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
790a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
791a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
792a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
793a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
794a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
795a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
796a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
797a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
798a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
799a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
800a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
801a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
802a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
803a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
804a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
805a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
806a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
807a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
808a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
8104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("John", "Doe");
8114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
8134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
8144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
8154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
8164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
8204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
8224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
8244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
8254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
8264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
8274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
8284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
8304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
8314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
8324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
83381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
8344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
83689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
83789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
83889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
83989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
84089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri1 = insertStructuredName(rawContactId1, "John", "Doe");
84189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
84289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri2 = insertStructuredName(rawContactId2, "Jane", "Doe");
84389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
84489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(dataUri1, account1);
84589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(dataUri2, account2);
84689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
84789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
84889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
84989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
8504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
8517d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
8523cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
8534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
8544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
8554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
8564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
8574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
8584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
8604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
8614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
8634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
8644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
8654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
8694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
8703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
8714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
8734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
8744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
8754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
8764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
8774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
8784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
8794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
8804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
8814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
8824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
88348828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
8844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
8854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
88847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
8895e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
8905e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
8912a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("Chilled", "Guacamole", ACCOUNT_2);
8922a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
8935e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
8944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "tamale");
8954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
8964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
8974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
8985e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
8994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
9004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
9015e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
9024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1-800-GOOG-411");
9045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
9055e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
9065e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "18004664");
9075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
9085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
9095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "encilada");
9105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
91145d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
91245d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "*");
91345d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
9144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
9154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
916e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
917e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
918e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
919e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
920e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
921e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
922e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
923e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
924e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
9254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
9264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
928e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
929e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
930e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
931e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
932e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
933e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
934e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
935e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
936e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
9374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(lookupUri1, values);
9384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
939892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
940892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // call id should not match to "8004664411"
941e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
942892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
943892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
944892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
945892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
946892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
947892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
948892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
949892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
950892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
951892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
952892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
953892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
954892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
955892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
956892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
957892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
958892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
959892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
960892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
961892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
962892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
963892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
964892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
965892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
966892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
967892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
968892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
969892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
970892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
971892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
972892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
973892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
974892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
975892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
976892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
977892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
978892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot1", "Tamale");
979892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
980892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
981892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
982892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
983892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
984892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
985892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
986892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
987892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
988892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
989892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
990892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
991892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
992892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
993892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
994892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
995892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
996892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
997892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
998892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot2", "Tamale");
999892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1000892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1001892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1002892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1003892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1004892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1005892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1006892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1007892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1008892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1009892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
10104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1012653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1013653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1014653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1015653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1016653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1017653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1018653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1019653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1020653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
10215870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri1, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1022653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1023653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1024653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1025653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1026653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1027653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
10285870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1029653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1030653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1031653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1032653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1033653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1034653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1035653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1036653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1037653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1038653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1039653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1040653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
10415870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(lookupUri2, PhoneLookup.DISPLAY_NAME, "Hot Tamale");
104281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1043653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1044653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
10454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
10464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
10484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
10494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
10504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
10514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
10524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
10544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
10554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
10574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertEmail(rawContactId, "meghan@acme.com");
10584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long emailId = ContentUris.parseId(uri);
10594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
10634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
10664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
10674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
10684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
10694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
10724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
10734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
10744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
10754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
107648828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
10774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
10784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10805e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
10814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Hot", "Tamale");
10824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
10834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10845e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
10854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
10874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
10884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
10914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
10924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
109308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
109408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
109508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
109608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
109708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
10984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
11005e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
110147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
11025e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
11035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
11045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
110547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Hot", "Tamale", ACCOUNT_2);
11065e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
11075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
11095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
11105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
11115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
11125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
11135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
11145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
11155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
11165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
11185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
11195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1120155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
11215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
11225e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11231e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
11245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
11255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
11275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
11285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
11295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11307d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1131c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1132c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1133c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
1134c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1135c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1136c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1137c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1138c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1139c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1140c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1141c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1142c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1143c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1144c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1145c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1146c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v1, v2, v3 });
1147c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1148c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1149c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1150c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1151c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1152c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
1153c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1154c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1155c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1156c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1157c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1158c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1159c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1160c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1161c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1162c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1163c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1164c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1165c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
11667d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
11677d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
11687d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
11697d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
11707d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId1 = createRawContact(ACCOUNT_1);
11717d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
11727d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId2 = createRawContact(ACCOUNT_2);
11737d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
11747d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
11757d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
11767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
11777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
11787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
11817d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_1.type)
11827d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11837d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
11847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
11877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_2.type)
11887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
11907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11917d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
11927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
11947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
11957d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2 });
11967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
11977d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
11987d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
11997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
12007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
12017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
12027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
120346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
120446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
120546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId1 = createRawContact();
12064928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
12074928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
120846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId2 = createRawContact();
12094928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
12104928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
12114928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
12124928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
121346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
121446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
121546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
121646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
121746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
121846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
121946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
122046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
122146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
122246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
122346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
122446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
122546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
122646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
122746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
122846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
122946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
123046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
123146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
123246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
123346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
123446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
123546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
123646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
123746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
123846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
12394928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
124046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
124146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // account3@email.com should be the first. account2@email.com should also be promoted as
124246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // it has same contact id.
124346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
124446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
124546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
124646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1247f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1248f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1249f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1250f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1251f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
1252f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long rawContactId1 = createRawContact();
1253f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1254f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1255f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1256f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1257f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1258f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1259f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1260f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1261f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1262f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1263f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1264f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1265f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1266f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1267f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1268f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1269f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1270f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1271f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1272f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1273f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1274f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1275f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1276f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1277f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1278f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1279f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1280f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1281f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1282f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1283f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1284f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1285f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1286f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1287f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1288f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1289f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1290f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1291f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1292f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1293f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1294f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1295f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1296f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1297f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1298f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1299f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1300f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1301f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1302f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1303f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1304f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1305f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1306f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1307f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1308f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1309f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1310f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1311f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
13124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
13134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Alice", "Nextore");
13144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
13154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
13164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
13184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
13204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
13214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
13224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
13234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
13244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
13254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
132648828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
132748828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
13324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1334aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1335d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
13364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
13374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
13394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
13404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
13434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1345aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1346aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
134782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1348aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
1349ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
1350ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
1351ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
13524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1354a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
13554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
135648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1357aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1358d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1359aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
136048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
136148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
136248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
136348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
13643b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
13653b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
13667ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, nameValues);
136748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
136848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
136982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
137048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1371ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
1372ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
13734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
137448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
13753b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
137648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1377a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
13783b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
13793b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
1380a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
13817ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13827ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
13837ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
13847ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
13857ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13867ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
13877ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
13887ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
13897ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
1390a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1391a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1392a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1393a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
1394a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1395a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1396a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1397a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1398a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1399a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1400a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1401a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1402a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1403a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1404a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1405a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
1406a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1407a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1408a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
1409a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
1410a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
1411a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
1412a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
1413a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1414a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
1415a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
1416a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1417a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1418a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1419a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
1420a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1421a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1422a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1423a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1424a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1425a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1426a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1427a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1428a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1429a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1430a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1431a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
1432a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1433a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1434a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
1435a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
1436a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
1437a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
1438a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1439a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
1440a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
1441a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
14424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
14442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
14452f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
14462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
14472f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
1448ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
14494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
14502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
14512f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
14524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
14532f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
1454d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
14554928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
14564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
14574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
1458aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
1459aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
14604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
14612f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
14622f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
14632f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
14642f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
1465d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
14664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
14674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values4, "Fay", "Veritt", "18004664414",
1468aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
1469d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
14704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
14712f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
14722f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
14732f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
14742f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14752f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
14764928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
14772f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14782f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
14792f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
14802f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
14812f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14824928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
14832f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
14844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
14852f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14862f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
14872f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
14884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
14892f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
14902f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // With phone-only parameter, the 1st contact shouldn't be returned, since it is only
14912f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // about email, not phone-call.
14922f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
14932f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
14942f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
14954928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
14964928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
14974928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
14984928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
14994928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
15004928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
15014928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
15024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1503ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
15042f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
15054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
15064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
150745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
150845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
150945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
151045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
151145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
151245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
151345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
151445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
151545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
151645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
151745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
151845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
151945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
152045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
152145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
152245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
152345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 0, 0, 0);
152445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
152545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
152645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
152745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
152845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
152945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
153045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
153145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
153245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
153345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
153445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
153545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
153645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
153745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
153845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
153945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
154045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
154145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
154245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
154345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
154445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
154545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
154645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
1547ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
15484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
15494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
15514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
1552aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
1553aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
15544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
15564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
1557aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
1558aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
15594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1560ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
15614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
15624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
15634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
15644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
15654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1567ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
15684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
15694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
15704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
15714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1573ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
15744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
15754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
15764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
15773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
15783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
157924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRequiresReadPermission() {
158024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
158124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
158224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
158324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
158424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Queries for the profile should fail.
158524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
158624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
158724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieving profile contact.
158824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
158924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI, null, null, null, Contacts._ID);
159024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile without READ_PROFILE access should fail.");
159124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
159224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
159324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
159424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
159524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
159624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
159724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
159824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
159924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
160024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
160124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, Contacts._ID);
160224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile data without READ_PROFILE access should fail.");
160324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
160424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
160524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
160624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
160724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
160824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
160924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
161024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
161124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
161224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon()
161324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("entities").build(), null, null, null, Contacts._ID);
161424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile entities without READ_PROFILE access should fail.");
161524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
161624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
161724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
161824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
161924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
162024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
162124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
162224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
162324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
162424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
162524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
162624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
162724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
162824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
162924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
163024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
163124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
163224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
163324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, Contacts._ID);
163424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the profile by contact ID without READ_PROFILE access should fail.");
163524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
163624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
163724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
163824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
163924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
164024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
164124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
164224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
164324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
164424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
164524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
164624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
164724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
164824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
164924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
165024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(RawContacts.CONTENT_URI,
165124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    profileRawContactId), null, null, null, RawContacts._ID);
165224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw contact profile without READ_PROFILE access should fail.");
165324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
165424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
165524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
165624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
165724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
165824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
165924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
166024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
166124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
166224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
166324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
166424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
166524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
166624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
166724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
166824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
166924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
167024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
167124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw contact profile without READ_PROFILE access should fail.");
167224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
167324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
167424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
167524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
167624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
167724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
167824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
167924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
168024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
168124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(
168224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
168324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("data").build(), null, null, null, null);
168424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw profile data 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        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
169324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
169424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(
169524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
169624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    .appendPath("entity").build(), null, null, null, null);
169724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the raw profile entities without READ_PROFILE access should fail.");
169824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
169924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
170024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
170124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
170224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
170324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
170424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
170524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
170624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
170724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
170824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
170924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
171024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
171124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
171224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
171324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
171424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
171524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
171624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
171724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
171824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
171924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, null);
172024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the data in the profile without READ_PROFILE access should fail.");
172124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
172224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
172324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
172424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
172524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
172624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
172724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
172824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
172924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
173024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
173124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
173224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
173324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
173424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
173524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
173624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
173724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                    null, null, null, null);
173824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Querying for the data in the profile without READ_PROFILE access should fail.");
173924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
174024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
174124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
174224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
174324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
174424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
174524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
174624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
174724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
174824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
174924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
175024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
175124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
175224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
175324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
175424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
175524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
175624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
175724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
175824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
175924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
176024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
176124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
176224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
176324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
176424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
176524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
176624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
176724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
176824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
176924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
177024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
177124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
17726ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
17736ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
17746ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
17756ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17766ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
17776ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long rawContactId = createRawContactWithName("Domo", "Arigato");
17786ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
17796ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
17806ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
17816ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
17826ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17836ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
17846ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
17856ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
17866ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
17876ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
17886ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
17896ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
17906ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
17916ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
17926ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
17936ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
179424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactIncludeProfile() {
179524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
179624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
179724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
179824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
179924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
180024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
180124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
180224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
180324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri contactWithProfilesUri = Contacts.CONTENT_URI.buildUpon()
1804377850d2dfd28eaf1b22273a50cfe066f6667ab9Dave Santoro                .appendQueryParameter(ContactsContract.ALLOW_PROFILE, "1").build();
180524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValuesOrderly(contactWithProfilesUri,
180624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new ContentValues[]{profileValues, nonProfileValues});
180724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(contactWithProfilesUri, profileValues, Contacts._ID, profileContactId);
180824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
180924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
181024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
181124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
181224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
181324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
181424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
181524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
181624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
181724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
181824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
181924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
182024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
182124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
182324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
182424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
182524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
182724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
182824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
182924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
183024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
183124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
183224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
183324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
183424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
183524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
183624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
183724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
183824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
183924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
184024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
184124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
184224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
184324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
184424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
184524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
184624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
184724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
184824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
184924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
185024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
185224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
185324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
185524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
185624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
185724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
185824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
185924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
186024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
186124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
186224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
186324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
186424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
186524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
186624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
186724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
186824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
186924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
187024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
187124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
187224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
187324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
187424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
187524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
187624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
187724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
187824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
187924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
188024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
188124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
188224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
188324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
188424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
188524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
188624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
188724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
188824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
188924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
189024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
189124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
189224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
189324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
189424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
189524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
189624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
189724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
189824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
189924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
190024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
190124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
190224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
190324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
190424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
190524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
190624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
190724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
190824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
190924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
19100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
191119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
191219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
191319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
191419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
191519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
191619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
191719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
191819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
191919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
192019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
192119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
192219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
192382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
1924aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
1925aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
192682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
1927aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
1928aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
192919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
193019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
193182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
193219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
1933a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
1934a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
193519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
193619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
193719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
193819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
193919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
194082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
19410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
194219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
194319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
194419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
1945a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
194619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
194719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
194819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
194919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
195019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
195182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
19520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
195319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
195419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
195519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
1956a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
195719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
195819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
195919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
196019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
196119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
196289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
196389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
196489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
196589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
196689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
196789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
196889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
196989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
197089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
197189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
197289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
197389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
197489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
19753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
19763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
19773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
19783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
19793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
19803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
19813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
19823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
19833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
19843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
19853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
19863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
19873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
198894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
19893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
19903cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
19913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
19923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
19933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
19943cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
19953cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
199673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
19973cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
19983cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
19993cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
2000f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
2001f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2002f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2003f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2004f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
2005f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2006f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
2007f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2008f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2009f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
2010f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2011f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2012f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2013f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2014f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
2015f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2016f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
2017f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2018f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2019f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
2020f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2021f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2022f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2023f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
2024f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
2025f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
2026f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
2027f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
2028f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
2029f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
2030f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
2031f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
2032f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
2033f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
2034f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2035f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2036f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
2037f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
2038f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
2039f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
2040f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
2041f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
2042f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2043f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
2044f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
2045f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId0 = createRawContactWithName("firstName0", "lastName0");
2046f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2047f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId1 = createRawContactWithName("firstName1", "lastName1");
2048f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
2049f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
2050f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2051f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId2 = createRawContactWithName("firstName2", "lastName2");
2052f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
2053f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
2054f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
2055f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2056f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2057f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
2058f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
2059f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
2060f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
2061f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
2062f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
2063f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
2064f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2065f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2066f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
2067f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
2068f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
2069f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
2070f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
2071f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
2072f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
2073f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2074f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
2075f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
2076f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
2077f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
2078f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
2079f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
2080f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
2081f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
2082f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2083f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2084f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2085f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
2086f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
2087f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
2088f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
2089f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2090f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2091f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2092f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
2093f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId3 = createRawContactWithName("firstName3", "lastName3");
2094f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
2095f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
2096f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
2097f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
2098f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2099f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2100f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2101f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2102f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Uri uri = Groups.CONTENT_SUMMARY_URI.buildUpon()
2103f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                .appendQueryParameter(Groups.PARAM_RETURN_GROUP_COUNT_PER_ACCOUNT, "true")
2104f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                .build();
2105f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
2106f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
2107f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
2108f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
2109f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2110f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
2111f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
2112f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
2113f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
2114f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
2115f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
2116f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
2117f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
2118f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
2119f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
2120f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
2121f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
2122f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
2123f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
2124f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
2125f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
2126f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2127f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
212889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
212989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
213089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
213189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
213289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
213389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
213489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
213589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
213689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
213789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
213889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0") ;
213989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
214089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1") ;
214189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
214289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
21434097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
2144d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
21454097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
21464097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
21475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
21484097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
214917a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
21504097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
21514097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
215267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
215367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        long rawContactId = createRawContact();
215467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
215567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
215667c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
215767c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
215867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        insertStructuredName(rawContactId, values);
215917a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
216067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
216167c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
21624097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
2163d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
21644097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
21654097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
21664097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
21675ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
21684097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
21695ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
21704097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
21714097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
21725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
21735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        final long rawContactId = createRawContact(null);
21745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
21765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
21775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
21785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
21795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
21805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
21815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
21825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
21845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
218555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
218655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
21875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
21885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
21895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
21905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
21915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
21935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
21945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
21955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
21965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
219755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
219855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
21995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
22005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
22015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
22025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
22035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
22055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
22065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
22075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
22095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
22105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
22115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
22135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // Only run this test when Chinese collation is supported
22155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
22165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
22175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
22185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
22205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
22225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
22235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
22245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
22275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
22285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
22295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
22305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
22314cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
22324cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
22335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
22355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
22365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
22395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
22405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
22415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
22425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
22434cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
22444cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
22455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
22475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
22485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
22495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
22515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
22525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
22535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
22555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
22565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
22585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
22595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
22605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
22615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
22645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
22655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
22665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
22675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
22685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
22695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
22705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
22725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
22735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
22755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
22765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
22775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
22785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
22795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
22805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
22815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
22825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
22845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
22855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
22865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
22875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
22885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
22895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
22905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
229125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
229225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId1 = createRawContact();
229325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
229425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
229525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId2 = createRawContact();
229625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
229725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
22980c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
22990c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
230025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
230125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
230225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
230325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertStructuredName(rawContactId2, "Potato", "Head");
230425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
230525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
230681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
230725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
230825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
230901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
231001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long rawContactId = createRawContact();
231101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2312a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
231301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
231401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
231501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
231601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
231701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
231801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
231901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
232001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
232101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
232201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
232301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
232401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
232501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2326a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
2327a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2328a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
23295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
233001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
233101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2332a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
2333a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
2334a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
2335a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
2336a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
2337a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2338a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
2339a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
2340a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
2341a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertStructuredName(rawContactId, values);
23425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
23435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
23445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
23465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
23475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
23485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
23495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
23515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
23535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
23545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
23555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
23565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
23575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
23595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
23605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
23615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
23625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
23645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
23655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
23665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
23675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
23685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
23695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
23705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
23715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
23735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
23745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
23755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
23765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
23785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
23805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
23815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
23825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
23835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
23845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
23865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
23875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
23885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
23895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
23905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
23915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
23925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
23935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
23945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
23950b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        boolean hasChineseCollator = false;
23960b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        final Locale locale[] = Collator.getAvailableLocales();
23970b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        for (int i = 0; i < locale.length; i++) {
23980b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            if (locale[i].equals(Locale.CHINA)) {
23990b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                hasChineseCollator = true;
24000b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                break;
24010b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            }
24020b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
24030b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
24040b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        if (!hasChineseCollator) {
24050b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
24060b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
24070b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
24085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
24095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
24105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
24115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
24135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
24155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
24165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
24175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
24185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
24195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
24205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
24215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
24225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
24234cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
24244cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
24255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
242601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
242701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
242831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
242931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long rawContactId = createRawContact();
243031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
243131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
243231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
243331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
243431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
243531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
243631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
243731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
243831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
243931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
244031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
244131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
244231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
244331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
244431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
244531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
244631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
244731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
244831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
244931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
245031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
245131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
245231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
245331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
245431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
245531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
245631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
245731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
245831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
245931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
246031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
246131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
246231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
246331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
246431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
246531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
246631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
246731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
246831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
246931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
247031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
247131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
247231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
247331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
247431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
247531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
2476a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
2477a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, filter);
2478a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
2479a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2480a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2481916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
2482916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2483916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2484916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2485916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
2486916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
2487916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2488916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2489916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2490916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
24919c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
2492916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
2493916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2494916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
2495916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
2496916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2497916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2498916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
2499916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
2500916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2501916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2502916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
2503916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2504916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2505916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("acme"));
2506916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2507916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2508916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
25093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "engineer, [acmecorp]");
2510916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2511916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2512916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2513916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
2514916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContact();
2515916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2516916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2517916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
25183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "John", "Doe");
2519916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2520916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2521916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("acme"));
2522916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2523916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2524916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
25253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[acme@corp.com]");
2526916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2527916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2528916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
25293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
25303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
25313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
25323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
25333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
25353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
25363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
25383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
25393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
25403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
25433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
25453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
25473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
25493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
25513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
25533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
25543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
25553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
25563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
2557916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
2558916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2559916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2560916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2561916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2562916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
2563916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2564916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("inc"));
2565916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2566916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2567916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
256830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        values.put(SearchSnippetColumns.SNIPPET, "[Incredible]");
2569916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2570916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2571916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
25723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
25733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
25743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
25753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
25763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
25773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
25793716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
25803716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
25813716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
25823716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
25843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
25853716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("john")),
25863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
25873716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
25883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25893716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
25903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
25913716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
25923716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
25933716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
25943716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
25953716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
25963716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
25973716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
25983716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
25993716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26003716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
26013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
26023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
26033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
26053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
26063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
26073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
26083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
26093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
26103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
26113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
26123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
26133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
26153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
26163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
26173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
26183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
26203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("aperture")), emptySnippet);
26213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
26223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
26243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
26253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
26263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
26273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
26283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
26303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
26313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
26323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
26333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("860")),
26353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
26363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
26373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
26393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
26403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
26413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
26423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
26433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
26453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
26463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
26473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
26483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
26493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode("cave")),
26503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                emptySnippet);
26513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
26523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
2653dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
2654dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long rawContactId = createRawContact();
2655dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, "Slinky", "Dog");
2656dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2657dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2658dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2659dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2660dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
2661dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2662dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
2663dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
2664dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2665dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2666dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
2667dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2668dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
2669dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2670dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2671dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
2672dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2673dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
2674dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
2675dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2676dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
2677dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
2678dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
2679d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
2680d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
2681d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
2682d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
2683d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
2684d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
2685d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
2686d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
2687d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
2688d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
2689d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
2690d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
2691d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
2692d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2693d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
2694d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
2695d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
2696d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
2697c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
2698d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2699d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2700d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
2701d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
2702d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
2703d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
2704d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
2705d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2706d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2707d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
2708c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
2709d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2710d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2711d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
2712d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
271381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
27148c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
27158c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
27168c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
27178c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
2718d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2719d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2720d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
27213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("a", "b");
2722d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2723d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
2724d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
27253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("c", "d");
2726d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2727d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
2728d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2729d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
27300c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
27310c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2732d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2733d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
2734d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
2735d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2736d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2737d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
27383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("e", "f");
2739d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2740d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
2741d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
27423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("g", "h");
2743d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2744d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
2745d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2746d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
27470c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
27480c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2749d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2750d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
27510c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
2752d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2753d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2754d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
27553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("i", "j");
2756d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
2757d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
2758d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
27593cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("k", "l");
2760d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
2761d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
2762d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2763d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
27640c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
27650c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2766d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2767d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
27680c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
27690c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
2770d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
27713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
2772d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
2773d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
2774d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
277582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
27764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        long rawContactId = createRawContact();
27770a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
27780a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
27790a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
27800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
27810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
27820a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
27830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
27840a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
27850a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
27860a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
27870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
27880a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
27890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
27900a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
27910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
27920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
27930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
27940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
27950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
27960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
27970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
27980a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
27990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
28000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
28010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
28020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
28030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
28040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
28050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
28060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
28080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
28100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
28110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
28120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
28130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
28140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
28150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
28160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
28170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
28190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
28200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
28210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
28220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
28230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
28240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
28250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
28260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
28270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
28290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
28300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
28310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
28320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
28340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
28350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
28360a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
28370a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
28380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
28400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
28420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
28430a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
28440a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
28450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
28470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
28480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
28490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
28500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
28514dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
28524dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
285382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
28544dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
28554dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
2856aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2857aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
28584dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
28594dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
2860aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
2861d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
28624dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
28634dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
2864aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
2865aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
28664dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
28674dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
2868aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
2869aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
28704dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
287182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
287282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
28730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
287482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
28754dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
287682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
28774dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
287882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
28794dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
288082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
28814dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
28824dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
2883bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2884bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2885bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2886bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2887bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
288882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
28890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2890bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2891bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
2892bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
289382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
2894bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long rawContactId = createRawContact();
2895bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2896bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2897bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2898bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2899bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2900bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
290182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
290282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
2903bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2904bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
2905aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
2906aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
2907aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
2908aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
290982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
2910aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2911aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
291282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
2913bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
291482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
291582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2916bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2917bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
29189705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
29199705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
29209705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
29219705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
29229705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
29239705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
29249705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
29259705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
29269705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
29279705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
29289705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
29299705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
29309705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
29319705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
29329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
29339705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
29349705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
29359705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
29369705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
29379705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
29389705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
29399705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
29409705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
29419705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
29429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
29439705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
29449705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
29459705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
29469705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
29479705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
29489705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
29499705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
29509705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
29519705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
29529705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
29539705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
29549705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
29559705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
29569705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
29579705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
29589705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
29599705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
29609705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
29619705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
296282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
29639705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
296482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
2965a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2966a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
2967a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
2968093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
2969093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long rawContactId = createRawContact();
2970093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2971093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2972093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
2973093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2974093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2975093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
2976093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
2977093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
2978093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
2979093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
2980093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2981093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
2982093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2983093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2984093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2985093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
2986093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
2987093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
2988093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
2989093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
2990093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
2991093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
2992093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
2993093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2994093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
2995093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
299682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
2997a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long rawContactId = createRawContact();
2998a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
2999a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
3000a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3001a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3002a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3003aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
3004aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3005aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
3006aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3007aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
3008aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3009a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3010a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
3011a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
301282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
301382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3014bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
30154dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
30164dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
301782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
301882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
30194dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
302082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
302182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
3022a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
302382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
30244dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
30254dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
30264dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
30273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
30283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
30303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
30313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
30333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
30343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
30363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
30373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
30383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
30413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
30433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
30453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
30463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
30483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
30493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
30503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
30533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
30553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
30563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
30583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
30593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
30613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
30623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
30633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
30663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
30683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
30693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
30713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
30723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
30733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
30743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
30753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
30763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
30773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
30783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
30813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
30833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
30843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
30853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
30863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
30883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
30893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
30903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
30913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
30933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
30943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
30953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
30963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
30973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
30983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
30993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
31013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
31023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
31033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
31063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
31083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
31093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
31103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
31123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
31133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
31143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
31153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
31173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
31183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
31193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
31213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
31223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
31233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
31263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
31283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
31303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
31313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
31323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
31343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
31356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
31363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
31373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
31383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
31403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
31413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
31423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
31453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
31483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
31493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
31503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
31513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
31533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
31543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
31553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
31563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
31583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
31593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
31606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
31613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
31633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
31646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
31656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
31663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
31676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
31683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
31703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
31713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
31723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
31733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
31743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
31763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
31773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
31793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
31803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
31813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
31823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
31843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
31853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
31863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
31873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
31893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
31903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
31913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
31926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
31933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
31943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
31953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
31966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
31976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
31983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
31993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
32006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
32013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
32033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
32043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
32053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
32063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
32073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
32083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
32093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
32113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
32123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
32133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
32143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
32153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
32163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
32173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
32203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemIntoOtherAccount() {
32223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
32233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
32253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(rawContactId, values, mAccountTwo);
32263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Stream insertion was allowed in another account's raw contact.");
32273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
32283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert stream items into account one's raw contact is forbidden.
32293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
32333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
32343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
32363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
32383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
32403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
32413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
32433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
32443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
32453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
32463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
32473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
32483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
32493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
32533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
32563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
32573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
32583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
32593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
32603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
32633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
32653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
32663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
32683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
32703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
32713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
32723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
32733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
32743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
32753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
32773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
32793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
32803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
32813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
32823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
32833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
32843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
32853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
32863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
32873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
32883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
32893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
32903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
32913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
32923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
32943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
32953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
32963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
32973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
32983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
32993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
33003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
33013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
33033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
33043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
33053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
33063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
33073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
33083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
33093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
33123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
33133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
33143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
33153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
33163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
33193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
33213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
33233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
33243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
33263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
33273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
33283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
33293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
33303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
33313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
33323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
33333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
33343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
33353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
33363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
33373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
33393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
33413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
33423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
33433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
33443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
33453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
33463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
33473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
33483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
33493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
33503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
33513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
33543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
33556802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
33566802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
33573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
33583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
33593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
33606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
33616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
33626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
33636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
33646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                assertInputStreamContent(expectedPhotoBytes,
33656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        mResolver.openInputStream(Uri.parse(photoUri)));
33666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
33673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
33683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
33693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
33703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
33733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
33753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
33773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
33783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
33793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
33803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
33813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
33823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
33833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
33843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
33853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
33873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
33883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
33893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
33903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
33913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
33923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
33933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
33943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
33953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
33963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
33973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
33983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
33993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemFromOtherAccount() {
34013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
34023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, mAccount);
34043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
34053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
34063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
34073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
34083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.update(maybeAddAccountQueryParameters(StreamItems.CONTENT_URI, mAccountTwo),
34093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    values, null, null);
34103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to update stream items inserted by another account");
34113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
34123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't update the stream items from another account.
34133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
34143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
34173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
34193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
34223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
34233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
34243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
34253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
34263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
34286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
34293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
34303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
34313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
34323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
34343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
34353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
34366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
34373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
34386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
34406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
34416802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
34426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
34433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
34463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
34493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
34503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
34513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
34523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
34533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
34556802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
34566802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
34573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
34583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
34593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
34613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
34626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
34633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
34646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
34656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
34666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
34676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
34686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
34693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemPhotoFromOtherAccount() {
34723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
34733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, mAccount);
34753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
34763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
34773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, mAccount);
34783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
34793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
34816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
34826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
34833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
34843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                maybeAddAccountQueryParameters(
34853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
34863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
34873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
34883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        mAccountTwo);
34893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
34903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.update(photoUri, photoValues, null, null);
34913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to update stream item photos inserted by another account");
34923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
34933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't update a stream item photo inserted by another account.
34943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
34953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
34983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
35003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
35033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
35043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
35083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
35103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
35113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
35123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
35143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
35153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
35163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
35173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
35203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
35233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
35273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
35293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
35303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
35313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
35333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
35343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
35353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
35363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemFromOtherAccount() {
35393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
35403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
35413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), mAccount));
35423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
35433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.delete(
35443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    maybeAddAccountQueryParameters(
35453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
35463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            mAccountTwo), null, null);
35473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to delete stream item inserted by another account");
35483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
35493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't delete a stream item from another account.
35503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
35513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
35543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
35563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
35583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
35593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
35603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
35613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
35623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
35633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
35643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
35653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
35663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
35673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
35693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
35703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
35713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
35723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
35733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
35743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
35753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
35763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
35773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
35803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
35823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
35833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
35843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
35853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
35866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
35873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
35883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
35893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
35903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
35913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
35923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
35943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoFromOtherAccount() {
35973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
35983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
35993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), mAccount));
36003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), mAccount);
36013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
36023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            mResolver.delete(maybeAddAccountQueryParameters(
36033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    Uri.withAppendedPath(
36043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
36053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                            StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
36063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    mAccountTwo), null, null);
36073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should not be able to delete stream item photo inserted by another account");
36083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
36093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Can't delete a stream item photo from another account.
36103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
36113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
36143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
36153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
36163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
36173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
36206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
36216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
36236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
36256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
36266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
36276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
36286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
36296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
36306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
36316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
36336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
36346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.TEXT, "hacking");
36356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
36366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
36376802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
36386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
36396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
36406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36416802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
36426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36436802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
36446802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
36456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
36466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
36476802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
36486802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
36496802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
36506802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36516802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
36526802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
36536802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
36546802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36556802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
36566802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
36576802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.TEXT, "finished hacking");
36586802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
36596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
36606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
36616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
36626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
36636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
36643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
36653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
36663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
36673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
36683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
36693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
36703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
36733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
36743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
36756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
36766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
36773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
36783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
368082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
3681bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
3682bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
3683bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3684d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact();
36854dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
3686bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3687aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
3688aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3689aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
3690aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3691aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
3692aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3693bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3694af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
369582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
36964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
3697bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3698bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
369982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
370082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
37010265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
3702bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
3703bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
3704d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
3705d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
3706d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
3707d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
3708d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
3709d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
3710d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
3711d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3712d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3713d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
3714d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
37158c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
37168c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
37178c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
37188c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
37198c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
37208c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
37218c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
37228c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
37238c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
37248c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
37258c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
37268c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
37278c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
3728d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3729d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3730d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
3731d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
3732d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3733d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3734d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3735d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
3736d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
3737d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
3738d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
3739d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
3740d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
3741d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
3742d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3743d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
37449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
37450be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
37460be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
37470be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
37480be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37490be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
37500be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
37510be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37520be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
37530be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
37540be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37550be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
37560be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
37570be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37580be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
37590be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
37600be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37610be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
37620be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
37630be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37640be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
37650be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
37660be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
37670be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37680be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
37690be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
37700be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
37710be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
37720be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
37730db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
37740db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
37750db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
37760db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
37770db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
37780db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
37790db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
37800db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
37810db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
37820db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
37830db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
37840db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
37850db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
37860db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
37870db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
37880db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
37890db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
37900db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
37910db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
37920db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
37930db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
37940db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
37950db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
37960db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
37970db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
37980db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
37990db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
38000db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
38010db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
38020db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
38030db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
38040db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
3805a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
38069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
38079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
38089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
38109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
38119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38123cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c0");
38133cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
38143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
38153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
38169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
3817226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c1 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c1");
38189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
38199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
38209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
38219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
38229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
3823226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c2 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c2");
38249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
38259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
38269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
38279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long c3 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c3");
38299261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
38309261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
38319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
38329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
383362318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
383462318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount), null,
383562318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
38369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
38379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
38389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
38396cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
38409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
38419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
38429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
38439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
38449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
38459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
38469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
38479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
38489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
38499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
38509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
38519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
38529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
38539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
38549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
38559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
38569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
38586cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
38599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
38609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
38619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
38629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
38639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
38649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
38659261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
38669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
38679261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
38689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
38699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
38709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
38719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
38736cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
38749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
38759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
38769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
38779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
38789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
38799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
38809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
38819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
38829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
38839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
38849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
38859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
38869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
38879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
38883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
38899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
389020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
389120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
3892d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
389320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
389420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
38955ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
389620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
389720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
389820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
389920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
390020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
390120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
390220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
390320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
390420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
390520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
390620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
390720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
390820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
390920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
391020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
391120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
391220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
391320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
391420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
391520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
391620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
391781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
391820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
391920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
392020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
392120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
392220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
392320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
392420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
392520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
392620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
392720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
392820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
392920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
393020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
393120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
393220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
393320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
393420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
393520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
393620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
393720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
39385ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
393920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
394081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
394170b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
394220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
394320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
39445ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
394520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
394620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
39475ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
394833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
394981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
395033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
395120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
395289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
395389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
395489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
395589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
395689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
395789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
395889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
395989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
396089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
396189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
396289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
396389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
396489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
396589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
396689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
396789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
396889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
396989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
397089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
3971373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
3972e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId = createRawContact(mAccount);
39735ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
397433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
39754dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
397682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
3977aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
3978aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3979a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3980a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
398133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
398233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
398382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
39844dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
398533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
398633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
398733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
39885870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
398981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
399033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
3991e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
399233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
399333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
399433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
399533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
399682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
39974dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
3998a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
399981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
4000a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
4001a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4002a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
4003e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId1 = createRawContactWithName(mAccount);
4004e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId2 = createRawContactWithName(mAccount);
400547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
400647fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
4007a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4008a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4009a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4010a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
4011e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
4012a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
4013a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
4014a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
401520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
40161fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
4017e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    public void testRawContactDeletionWithAccounts() {
4018e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        long rawContactId = createRawContact(mAccount);
4019e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
4020e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4021e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
402282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4023aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4024aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4025e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
4026e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
402782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
4028e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
4029e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4030e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
4031e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
4032e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4033e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
4034e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
4035e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
4036e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        mResolver.delete(deleteWithWrongAccountUri, null, null);
4037e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
40385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
4039e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4040e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
4041e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
4042e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4043e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
4044e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
4045e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
4046e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        mResolver.delete(deleteWithCorrectAccountUri, null, null);
4047e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
40485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
4049e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
4050e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4051627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
405270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
405370d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
405470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        long rawContactId3 = createRawContactWithName("James", "Sullivan");
405570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
4056627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
4057743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
405870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
405970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4060bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
4061743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
4062743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
4063dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
4064dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
406570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
4066743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
4067743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
4068743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId2 = createRawContact(mAccountTwo);
4069743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
4070743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
4071743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4072aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4073aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4074743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
4075bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
4076743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
4077627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
407882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
407970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
408070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
408170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
408233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
408333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
408433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4085bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
408633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
408733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
408833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", readOnlyAccount);
408933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
409033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("john", "doe", mAccount);
409133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
409233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
409333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
409433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
409533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
409633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
409733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
409833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
409933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
410033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
410133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
410233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
410333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
410433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
410533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
410633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
410733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4108bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
410933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
411033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
411133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
411233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
411333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
411433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
411533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
411633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
411733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
411833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
411933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
412033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
412133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
412233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4123cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
412447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", ACCOUNT_1);
412547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("John", "Doe", ACCOUNT_2);
4126cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4127cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4128cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4129cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
4130cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4131cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
4132cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4133cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
4134cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4135cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
4136cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
413773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
413873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
413973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
414073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
414173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri uri = insertStructuredName(rawContactId, "John", "Doe");
414273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
4143e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
414473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
414573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
414673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
414773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
41485870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
414973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
415081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
41511fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
41521fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
415361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
4154d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
4155d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
415673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
41571fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
41581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
41591fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
41601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
41611fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
416261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
4163c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
416461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
41651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
41661fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
41671fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
41681fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
416981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
41701fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
417161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
417261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
417381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
41741fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
41751fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
417661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
41771fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
417861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
417961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
418061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
41811fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
418281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
41831fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
41841fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
418561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
41861fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
418761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
41881fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
418981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
41901fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
41911fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
419261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
41931fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
419461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
419561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
419661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
419761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
419861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
419961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
42001fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
420161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
42021fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
42031fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
42041fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
42051fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
42061fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
42071fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
42081fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
420961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
421061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
42111fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
421261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
42131fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
421461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
421561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
421661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
421761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
42185870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
421961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
422081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
422161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
422261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
42231fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
42244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
42259fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
42269fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
42279fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
42289fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42299fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
42309fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42319fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
42329fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
42339fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
42349fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42359fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
42369fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
42379fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
42389fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42399fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
42409fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
42419fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
42429fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42439fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
42449fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
42459fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
42469fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
42479fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
42489fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
42499fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
42509fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
425160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
425260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
425360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
425460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
425560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
425660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
425760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
425860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
425960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
426060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
426160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
426260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
426360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
426460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
426560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
426660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
426760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
426860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
426960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
427060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
427160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
427260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
427360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
427460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
427560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
427660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
4277074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
4278074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
4279074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
4280074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
4281074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
4282f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4283f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
4284f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
4285f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
4286f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
4287074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
42883d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
42893d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
4290f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
4291074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
4292074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
4293ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
4294e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov        long rawContactId = createRawContact();
4295f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4296f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4297f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
4298f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
4299f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
4300e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
4301f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.DISPLAY_PHOTO),
4302f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4303f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.THUMBNAIL),
4304f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
4305ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
4306ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
4307ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    private static void assertInputStreamContent(byte[] expected, InputStream is)
4308ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            throws IOException {
4309ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        try {
4310ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            byte[] observed = new byte[expected.length];
4311ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            int count = is.read(observed);
4312ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(expected.length, count);
4313ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(-1, is.read());
4314ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            MoreAsserts.assertEquals(expected, observed);
4315ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        } finally {
4316ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            is.close();
4317ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        }
4318e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov    }
4319e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
4320732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
4321732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId1 = createRawContact(new Account("a", "a"));
4322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
4323732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
4324732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4325732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId2 = createRawContact(new Account("b", "b"));
4326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
4327732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
4328732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4329732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
4330732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4331732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4332732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
4333732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
4334f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4335f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
4336f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
4337f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
4338f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
4339732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
4340f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
4341732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4342732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
4343732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4344732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4345732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
4346732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
4347732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
4348732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4349732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
4350732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
4351732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
4352732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
4353732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
4354732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
4355732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
4356732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
4357732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
4358732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
43598e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
43608e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
43618e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
43628e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
43638e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
43648e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
43658e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
43668e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
43678e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
43688e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
43698e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
43708e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
43718e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
43728e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
43738e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
43748e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
4375155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
43768e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
43778e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
43788e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
43798e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
438081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
43818e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
4382f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
43838e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
43848e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
43858e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
43864e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
43877d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
43887d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
43897d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
43907d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
43917d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
43927d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
43937d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
43947d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
43957d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
43967d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
43977d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
43987d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
43997d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
44007d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
44017d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
44027d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
44037d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
44047d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
44057d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
44067d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
44077d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
44087d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
44097d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
44107d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
44117d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
44127d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
44137d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
44144e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
44157d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
44164e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
4417f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
44180265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
44197d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
44207d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
4421f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
4422f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4423f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4424f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4425f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
4426f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
4427f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4428f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4429f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4430f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4431f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4432f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4433f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
4434f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4435f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4436f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
4437f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4438f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
4439f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
4440f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4441f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4442f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4443f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4444f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4445f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4446f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
4447f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4448f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4449f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
4450f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4451f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
4452f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
4453f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
4454f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
4455f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4456f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4457f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4458f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4459f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4460f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
4461f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4462f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4463f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
4464f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4465f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4466f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4467f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4468f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
4469f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4470f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4471f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
4472f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4473f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4474f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
4475f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4476f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
4477f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4478f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4479f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4480f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4481f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
4482f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4483f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4484f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4485f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
4486f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4487f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4488f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4489f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
4490f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4491f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
4492f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
4493f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4494f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4495f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4496f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4497f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
4498f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4499f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4500f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4501f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
4502f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4503f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
4504f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
4505f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
4506f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4507f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4508f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
4509f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4510f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4511f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4512f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
4513f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
4514f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
4515f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4516f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4517f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
4518f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4519f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
4520f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4521f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4522f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4523f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
4524f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4525f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
4526f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
4527f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4528f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
4529f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
4530f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4531f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
4532f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4533f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
4534f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4535f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4536f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4537f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testWriteNewPhotoToAssetFile() throws IOException {
4538f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4539f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4540f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4541f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
4542f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
4543f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4544f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
4545f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
4546f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4547f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4548f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        OutputStream os = mResolver.openOutputStream(writeablePhotoUri, "rw");
4549f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
4550f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.write(originalPhoto);
4551f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
4552f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.close();
4553f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
4554f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4555f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
4556f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
4557f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4558f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
4559f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
4560f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4561f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4562f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
4563f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
4564f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4565f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
4566f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4567f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
4568f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4569f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4570f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
4571f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
4572f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4573f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4574f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws IOException {
4575f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4576f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4577f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4578f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
4579f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
4580f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
4581f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4582f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4583f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
4584f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
4585f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4586f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
4587f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
4588f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
4589f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
4590f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        OutputStream os = mResolver.openOutputStream(writeablePhotoUri, "rw");
4591f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
4592f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.write(originalPhoto);
4593f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
4594f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            os.close();
4595f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
4596f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4597f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
4598f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
4599f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
4600f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
4601f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4602f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
4603f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
4604f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
4605f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
4606f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4607f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
4608f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
4609f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
4610f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
4611f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
4612f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4613f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4614f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4615f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
4616f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
4617f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
4618f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
4619f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
4620f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4621f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4622f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
4623f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
4624f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4625f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
4626f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
4627f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4628f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
4629f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId1 = createRawContactWithName();
4630f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
4631f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
4632f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
4633f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
4634f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4635f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4636f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId2 = createRawContactWithName();
4637f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
4638f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
4639f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
4640f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
4641f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4642f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4643f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
4644f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
4645f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
4646f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
4647f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
4648f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
4649f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
4650f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
4651f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
4652f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
4653f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4654f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
4655f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
4656f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId3 = createRawContactWithName();
4657f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
4658f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
4659f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
4660f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
4661f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
4662f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
4663f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
4664f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
4665f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
4666f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4667f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
4668f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
4669f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
4670f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
4671f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4672f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
4673f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
4674f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4675f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
4676f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4677f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
4678f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
4679f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
4680f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4681f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4682f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
4683f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
4684f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
4685f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4686f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
4687f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4688f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
4689f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
4690f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
4691f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
4692f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4693f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
4694f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
4695f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4696f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4697f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
4698f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
4699f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
4700f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4701f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4702f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
4703f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4704f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
4705f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
4706f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4707f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
4708f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
4709f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
4710f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
4711f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4712f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
4713f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
4714f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
4715f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
4716f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
4717f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
4718f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
4719f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
4720f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
4721f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
4722f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
4723f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
47244e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
47254e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId1 = createRawContactWithName();
47264e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
47274e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId2 = createRawContactWithName();
47284e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
472947fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
473047fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
47314e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47324e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
47334e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
47344e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
47354e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47364e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
47374e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
47384e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47394e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
47404e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47414e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
47424e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
47434e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
47444e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47454e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
47464e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
47474e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47484e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
47494e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
47504e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
47514e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47524e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
47534e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
47544e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47554e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
47564e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
47574e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
47584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
47594e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
47606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
47616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId1 = createRawContact(new Account("a", "a"));
47626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
47636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
47646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId2 = createRawContact(new Account("b", "b"));
47666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
47676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
47686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
47706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
47716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
47726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
47736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
47746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
47756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
47766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
47776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
47796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
47806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
47816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
47826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
47836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
47856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
47866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
47876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
47886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
47896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
47916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
47926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
47936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
47946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
47956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
47966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
47976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
47986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
47996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
48006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
48016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
48026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
48036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
48046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
48056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
48086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
48096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
48106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
48116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
48126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
48136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
48146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
48156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
48176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
48186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
48196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
48206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
48216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
48246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
48256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
48266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
48276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
48296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
48306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
48316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
48326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
48336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
48366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
48376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
48386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
48396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
48416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
48426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
48436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
48446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
48456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
48486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
48496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
48506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
48516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
48526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
48536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
48546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
48556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
48566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
48586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
48596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
48606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
48616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
48626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId = createRawContact(new Account("a", "a"));
48636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
48646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
48666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
48676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
48686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
48696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
48726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
48736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
48756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
48766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
48776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
48786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
48806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
48816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
48826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
48836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
48856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
48866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
48876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
48886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
48896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
48906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
48916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
48926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
48936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
48946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
48956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
48966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
48976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
48986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
48996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
49006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
49016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
49026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
49036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
49046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
49056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
49066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
49076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
49086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
49096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
49106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
49116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
49126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
49136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
49146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
49156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
49161b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    public void testLiveFolders() {
49171b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId1 = createRawContactWithName("James", "Sullivan");
49181b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        insertPhoneNumber(rawContactId1, "5234567890");
49191b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
49201b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49211b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Mike", "Wazowski");
49221b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
49231b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        storeValue(Contacts.CONTENT_URI, contactId2, Contacts.STARRED, "1");
49241b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49251b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long rawContactId3 = createRawContactWithName("Randall", "Boggs");
49261b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long contactId3 = queryContactId(rawContactId3);
49271b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        long groupId = createGroup(NO_ACCOUNT, "src1", "VIP");
49281b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        insertGroupMembership(rawContactId3, groupId);
49291b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49301b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
49311b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
49321b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts"),
49331b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId1, "James Sullivan",
49341b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId2, "Mike Wazowski",
49351b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId3, "Randall Boggs");
49361b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49371b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
49381b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
49391b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts_with_phones"),
49401b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId1, "James Sullivan");
49411b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49421b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
49431b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
49441b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/favorites"),
49451b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId2, "Mike Wazowski");
49461b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49471b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertLiveFolderContents(
49481b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                Uri.withAppendedPath(Uri.withAppendedPath(ContactsContract.AUTHORITY_URI,
49491b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                        "live_folders/contacts"), Uri.encode("VIP")),
49501b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                contactId3, "Randall Boggs");
49511b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    }
49521b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
49531b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    private void assertLiveFolderContents(Uri uri, Object... expected) {
49541b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        Cursor c = mResolver.query(uri, new String[]{LiveFolders._ID, LiveFolders.NAME},
49551b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov                null, null, LiveFolders._ID);
49561b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        assertEquals(expected.length/2, c.getCount());
49571b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        for (int i = 0; i < expected.length/2; i++) {
49581b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertTrue(c.moveToNext());
49591b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertEquals(((Long)expected[i * 2]).longValue(), c.getLong(0));
49601b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov            assertEquals(expected[i * 2 + 1], c.getString(1));
49611b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        }
49621b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov        c.close();
49631b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov    }
49641b7a7947242bb3b8caaed871775e62d486144c9fDmitri Plotnikov
4965ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
4966ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
4967ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
4968ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4969ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContact();
4970ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("James", "Sullivan");
4971ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("The Abominable", "Snowman");
4972ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mike", "Wazowski");
4973ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("randall", "boggs");
4974ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Boo", null);
4975ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mary", null);
4976ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Roz", null);
4977ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4978ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
4979ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
4980ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_PRIMARY + " COLLATE LOCALIZED");
4981ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4982ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, null, "B", "J", "M", "R", "T");
4983ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
4984ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
4985ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4986ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
4987ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
4988ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
4989ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4990ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", null);
4991ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
4992ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
4993ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
4994ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
4995ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
4996ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
4997ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
4998ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
4999ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5000ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5001ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
5002ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
5003ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
5004ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
5005ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5006ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5007f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
5008f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
5009f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
5010f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
5011f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
5012f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
5013f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
5014f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
5015f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
5016f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
5017f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
5018f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
5019f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5020f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5021f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
5022f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
5023f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
5024f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
5025f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5026f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5027f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
5028f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
5029f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
5030f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
5031f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
5032f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
5033f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
5034f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
5035f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
50365fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
50375fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
50385fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
50395fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
50405fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
50415fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
50425fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
50435fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
50445fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
50455fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
50465fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
50475fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
50485fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
5049f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5050f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5051e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
5052e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
5053e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
5054e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
5055e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5056e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
5057e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
5058e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5059e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5060e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5061e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5062e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5063e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
5064e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
5065e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
5066e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
5067e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5068e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
5069e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
5070e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
5071e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5072e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri insertUri = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, blue);
5073e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5074e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
5075e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
5076e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5077e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5078e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5079e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5080e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
50813826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
50823826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
50833826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
50843826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
50853826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
50863826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        long rawContactId = createRawContact();
50873826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
50883826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
50893826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
50903826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
50913826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
50923826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
50933826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
50943826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
5095bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{ACCOUNT_1});
50963826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{ACCOUNT_1});
50973826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
5098bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
50993826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
51003826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
51013826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
51023826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
51033826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
510409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
510509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
510609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
510709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
51083826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
510909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
511009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
511109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
5112b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
5113743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
5114b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
5115b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
5116b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
5117b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
5118b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
5119b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
5120b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
5121b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
5122b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
5123b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
5124b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
5125b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
512642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
512742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
512842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
512942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
513042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
513142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
513242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
513342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
513442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
513542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
513642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
513742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
513842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
513942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
514042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
514142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
514242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
514342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
514442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
514542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
514642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
514742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
514842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
514942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
515042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
515142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId1 = createRawContact(mAccount, RawContacts.SOURCE_ID, "4:12");
515242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId1, "John", "Doe");
515342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
515442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId2 = createRawContact(mAccount, RawContacts.SOURCE_ID, "3:4%121");
515542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId2, "Jane", "Doh");
515642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
515742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
515842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
515942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
516042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
516142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
516242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
516342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
516442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
516542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
516642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
516742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
516842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
516942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
517042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
517142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
517242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
517342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
517442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
517542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
517642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
517742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
517842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
517942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
518042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
518142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
518242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
518342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
518442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
518542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
518642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
518742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
518842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
518942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
519042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
519142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
519242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
519342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
519442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
519542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
519642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
519742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
519842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
519942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
520042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
520142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
520242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
520342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
520442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
520542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
520642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
520742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
520824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
520924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
521024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
521124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
521224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
521324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
521424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
521524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
521624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
521724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
521842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
521942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
522042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
522142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
522242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
522342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
522442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
522542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
522642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
522742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
522842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
522942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
523042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
523142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
523242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
523342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
523442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
523542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
523642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
523742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
523842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
523942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
524042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
524142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
524242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
524342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
524442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
524524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
524624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
524724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
524842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
524942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
525042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
525142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
525242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
525342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
525442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
525542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
525642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
525742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
525842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
525942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
526042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
526142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
526242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
5263dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
5264dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
5265dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5266dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
5267dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
5268dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5269dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccountTwo);
5270dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(null);
5271dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5272dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5273dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5274dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5275dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5276dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5277dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5278dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5279dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5280dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5281dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5282dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
5283dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5284dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5285dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
5286dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
5287dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5288dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5289dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5290dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5291dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5292dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5293dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
5294dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5295dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5296dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount);
5297dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo);
5298dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
5299dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null);
5300dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5301dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5302dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5303dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5304dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
5305dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5306dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
5307dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5308dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5309dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5310dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5311dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5312dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
5313dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
5314dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
5315dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
5316dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
5317dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
5318dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
5319dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5320dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount, RawContacts.STARRED, "1");
5321dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo, RawContacts.STARRED, "1");
5322dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
5323dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null, RawContacts.STARRED, "1");
5324dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r7 = createRawContact(null);
5325dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5326dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5327dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5328dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5329dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5330dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
5331dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
5332dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5333dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5334dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5335dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5336dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
5337dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
5338dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
5339dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
5340dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5341dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5342dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5343dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5344dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5345dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5346dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5347dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5348dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5349dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5350dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5351dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5352dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5353dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5354dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5355dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
5356dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
5357dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
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            assertTrue(c.moveToNext());
5365dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5366dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5367dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5368dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5369dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
5370dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5371dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5372dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5373dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5374dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5375dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
5376dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5377dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5378dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5379dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5380dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5381dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5382dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5383dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
5384dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
5385dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
5386dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
5387dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5388dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5389dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
5390dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5391dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
5392dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
5393dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
5394dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
5395dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5396dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
5397dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5398dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5399dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
5400dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5401dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5402dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5403dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5404dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5405dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5406dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5407dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5408dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5409dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5410dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
5411dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5412dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5413dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5414dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5415dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5416dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
5417dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
5418dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
5419dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
5420dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
5421dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5422dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5423dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5424dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5425dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5426dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5427dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5428dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5429dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5430dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5431dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5432dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5433dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
5434dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5435dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5436dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5437dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5438e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
5439dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
5440dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5441dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
5442dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
5443dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
5444dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
5445dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
5446dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5447dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5448dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5449dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5450dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5451dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5452dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5453dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5454dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5455dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5456dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5457dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
5458dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
5459dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
5460dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5461dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5462dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5463dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5464dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
5465dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
5466dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
5467dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
5468dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
5469dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
5470dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
5471dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
5472dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5473dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5474dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5475dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5476dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5477dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
5478dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5479dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
5480dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
5481dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
5482dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
5483dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
5484dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5485dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5486dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5487dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
5488dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5489dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5490dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
5491dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
5492dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5493dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5494dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5495dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5496dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5497dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
5498dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
5499dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
5500dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5501dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5502dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5503dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
5504dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5505dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5506dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5507dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
5508dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
5509dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
5510dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5511dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5512dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
5513dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5514dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
5515dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
5516dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
5517dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
5518dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
5519dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
5520dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
5521dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
5522dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
5523dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
5524dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
5525dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
5526dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
5527dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
5528dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
5529dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
5530dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
5531dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
5532dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5533dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
553497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
553597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
553697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
553797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
553897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
553997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
554097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
554197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
554297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
554397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
554497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
554597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
554697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
554797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
554897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
554997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
555097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
555197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
555297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
555397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
555497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
555597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
555697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
555797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
555897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
555997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
556097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
556197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
556297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
556397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
556497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
556597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
556697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
556797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
556897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
556997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId1 = createRawContact();
557097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
557197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
557297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
557397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId2 = createRawContact();
557497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
557597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
557697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
557797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
557897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
557997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
558097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
558197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
558297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
558397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
558497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
558597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
558697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
558797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
558897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
558997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
55907a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
55917a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
55927a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
55937a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
55947a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
55957a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
559617a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
55977a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
55987a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
55997a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
56007a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
56017a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
56027a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
56037a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
56047a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
56057a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
56067a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
56077a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
56087a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
56097a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
56107a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
56117a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
56127a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
56137a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
56147a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
56157a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
56167a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
561755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
56187a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
56197a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
56207a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
56217a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
56227a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
56237a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
56247a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
56257a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
56267a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
56277a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
56287a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
5629dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
5630dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = mResolver.query(maybeAddAccountQueryParameters(Data.CONTENT_URI, account),
5631dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
5632dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
5633dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
5634dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
5635dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
5636dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
563742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
563842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
5639bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
564042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
564142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
5642bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
5643bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
5644bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
5645bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
5646bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
5647bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
5648bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
564942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
5650bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
5651bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
565242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
565342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
565442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
565542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
565642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
565742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
5658f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
5659f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
5660f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
5661f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5662f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
56634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
56644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
5665aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
566624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
566724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
566824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
566924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
567024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
567124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
567224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
567348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
567424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
567548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
567648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
567748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
567848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
5679aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
568048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
5681aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
568248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        insertStructuredName(rawContactId, firstName, givenName);
568348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
568448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
568548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
568624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
568724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
568824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
568924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
569024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
569124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        insertStructuredName(rawContactId, firstName, givenName);
569224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
569324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
569424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
569548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
5696aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
569724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
569824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
569924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
570024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
570124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
570224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
570324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
57044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
57054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
57064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
57074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
570824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
570924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
571024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
571124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
571224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
57134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
57144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
57154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
57164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
5717f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov        insertPhoneNumber(rawContactId, phoneNumber);
5718f992bfab334b760d36a053fc0b439382dcfb51adDmitri Plotnikov        insertEmail(rawContactId, email);
57194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
5720aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
5721aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                chatMode);
57224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
57234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
57244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
57254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
572624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
572748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
57284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
57294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
573024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
573124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
573224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
573324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
573424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
573524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
573624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
573724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
573824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
573924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
574024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
574124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
574224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
574324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
574424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
574524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
574624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
574724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
574824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
574924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
575024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
575124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
575224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
575324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
575424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
575524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
575624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
575724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
57584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
57594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
57604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
57614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
57624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
57634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
57644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
57654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
57664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
57674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
57684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
57694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
57704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
57714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
57724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
57734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
57744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
57754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
57764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
57774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
57784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
57794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
57804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
57814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
57824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
57834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
57844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
57854928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
57864928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
57874928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
57884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
57894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
57904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
57914928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
57924928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
57934928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
57944928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
57954928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendPath(String.valueOf(dataId))
57964928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
57974928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .build();
57984928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertNotSame(0, mResolver.update(feedbackUri, new ContentValues(), null, null));
57994928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
58004928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
58014928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
58024928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
5803d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
5804d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5805