ContactsProvider2Test.java revision c23a30e0510cf56d1dafddc79d1ab99ae9297a3f
1d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/*
2d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Copyright (C) 2009 The Android Open Source Project
3d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
4d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
5d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * you may not use this file except in compliance with the License.
6d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * You may obtain a copy of the License at
7d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
8d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
9d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
10d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
11d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
12d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * See the License for the specific language governing permissions and
14d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * limitations under the License.
15d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
168920a04b4a68ed6b548bcdef5ca8736dcf8b69b1Omari Stephens
1728f8857b1b46bde18b85c6d3c2a63ac44c3c2e1cEvan Millarpackage com.android.providers.contacts;
18d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
19d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport com.android.internal.util.ArrayUtils;
20dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
21f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawaimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
23b38ed2c5ffeb20efc677b4a9229db4a00603aa8dDmitri Plotnikovimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
24f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport com.android.providers.contacts.tests.R;
2524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport com.google.android.collect.Lists;
269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport com.google.android.collect.Sets;
27d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
2870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wongimport android.accounts.Account;
29d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderOperation;
30d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderResult;
31d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentUris;
32d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentValues;
339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.content.Entity;
3433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.content.EntityIterator;
3542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport android.content.res.AssetFileDescriptor;
36d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.database.Cursor;
37d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.net.Uri;
38c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoroimport android.os.AsyncTask;
39c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract;
40d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
41e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Callable;
42dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
43dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
44dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
45dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
46dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
47dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
48e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
49dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
50dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
51ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikovimport android.provider.ContactsContract.ContactCounts;
52c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.provider.ContactsContract.Data;
5446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawaimport android.provider.ContactsContract.DataUsageFeedback;
55dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.Directory;
565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
57f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.DisplayPhoto;
587a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
593cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.ContactsContract.Groups;
604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
6224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
6309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
6433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6562318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
66916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikovimport android.provider.ContactsContract.SearchSnippetColumns;
6789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
6882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
70f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
71dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
727d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
73d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
74f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
75d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
7642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
7742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
78ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringertimport java.io.InputStream;
79f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport java.util.Set;
865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
87d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
88d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
89d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
90d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
91d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
9223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki   adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
9323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki           com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
94d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
95d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
96d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
97d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
98d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
9947fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_1 = new Account("account_name_1", "account_type_1");
10047fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov    private static final Account ACCOUNT_2 = new Account("account_name_2", "account_type_2");
10147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
102dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
103dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
104dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
105dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
106dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
107dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
108dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
109dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
110dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
111dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
112dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
113dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
114dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
115dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
116dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
117f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1183d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1193d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
120dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
121dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
122dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
12324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
124dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
125dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
126dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
127dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
128dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
129dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
133dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
134dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
135dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
136dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
137dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
138dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
139dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
140dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
142dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
143dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
144dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
147dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
148dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
149dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
150dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
151dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
152f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1533d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1543d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
155dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
156dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
157dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
15824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
159dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
160dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
161dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
162dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
163dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
164dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
165dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
166dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
167dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
168dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
16930cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
170dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
171dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
172dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
173dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
174dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
175dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
176dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
177dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
178dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
17943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
18043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
181dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
182dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
18324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
184dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
185dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
186dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
187dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
188dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
189dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
190dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
191dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
192dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
193dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
194dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
195dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
196dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
197dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
198dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
199dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
200dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
201dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
202dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
203dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
204dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
205dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
206dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
207dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
208dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
209dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
210dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
211dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
212dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
213dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
214dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
215dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
216dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
217dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
218dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
219dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
220dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
221dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
222dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
223dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
224dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
225dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
226dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
227dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
228dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
229dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
230dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
231dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
232dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
233dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
234dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
235dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
236dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
237dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
238dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
239dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
240dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
241dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
242dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
243dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
244dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
24543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
24643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
25124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
252dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
253dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
254dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
255dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
257dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
258dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
259dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
260dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
261dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
264dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
265f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2663d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2673d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
268dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
269dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
272cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
273dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
274dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
278dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
283dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
284dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
288dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
295dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
298dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
299dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
309dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
310dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
311dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
312dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
313dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
32024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
326dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
327dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
328dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
329dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
334f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3353d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3363d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
337cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
345dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
346dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
347dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
348dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
349dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
350dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
351dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
352a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
353a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
354a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
355a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
356a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
357a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
358a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
359a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
360a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
361a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
362a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
363a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
364a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
365a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
366a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
367a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
368a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
369a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
370a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
371a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
372a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
373a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
374a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
375a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
376a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
377a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
378a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
379a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
380a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
381a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
382a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
383a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
384a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
385a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
386a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
387a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
388a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
389a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
390a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
391a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
392a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
393a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
39443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
39543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
396a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
397a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
398a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
399a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
400a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
402a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
403a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
404a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
405a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
406a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
407a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
408a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
409a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
410a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
411a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
412a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
413a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
414a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
415a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
416a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
417a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
418f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4193d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4203d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
421a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
422a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
42324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
424a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
425a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
426cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
427a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
428a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
429a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
430a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
431a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
432a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
433a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
434a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
435a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
436a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
437a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
44543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
44643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
449dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
450dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
451dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
45724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
460dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
461dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
462dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
463dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
466dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
470dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
471dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
472dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
482dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
483dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
484dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
485dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
486dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
487dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
488dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
489dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
490dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
491dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
492dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
493dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
494dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
495dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
496dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
4973d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
4983d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
499dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
500dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
501dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
502dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
503dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
504dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
5052530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
506dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
507dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
508dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
509dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
510dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
511dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
512dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
513dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
51443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
51543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
516dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
517dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
518dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
519dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
520dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
521dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
522dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
523dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
524dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
525dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
526dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
527dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
528dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
529c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
530dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
531dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
532dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
533dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
534dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
535dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
536dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
537dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
538dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
539dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
540dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
541dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
54243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
54343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
544dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
545dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
546dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
547dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
548dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
549dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
550dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
551dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
552dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
553dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
554dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
555dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
556dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
557c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
558dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
559dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
560dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
561dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
562dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
563dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
56418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
565dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
566dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
567dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
568dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
569dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
570dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
571dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
572dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
573dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
574dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
575dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
576dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
577dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
578dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
579dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
580dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
581f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET,
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
587dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
588dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
589dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
599dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
614dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
618778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
619778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
620dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
621dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
622dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
6233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
6243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
6253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
6273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
6289d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(RawContacts.DATA_SET, "ds");
6293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
6303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
6313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
6323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
6333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
6343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
6353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
6363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
6373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
6383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
6393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
6403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
6413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
6423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
6444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
6453cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6463cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
6474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
64881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
6493cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
6503cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
6512149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
6522149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
6532149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6542149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long rawContactId = createRawContactWithName();
6552149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
6562149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
6572149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6582149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
6592149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
6602149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6612149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
6622149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
6632149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6642149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6652149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6662149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6672149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
6682149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
6692149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
6702149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6712149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6722149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
6732149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
6742149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
6752149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
6762149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6772149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6782149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
6792149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
6802149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
6812149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
6822149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
6832149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6842149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6852149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6862149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
6872149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6882149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6892149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
6902149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
6912149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
6922149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
6932149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
6942149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
6952149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
696a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
697a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
698a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
699a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
700a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
701a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
702a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
703a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
7045d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
705a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
706a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
707a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
708a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
709a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
710a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
711a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
712a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
713a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
714a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
715a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
716a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
717a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
718a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
719a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
720a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
721a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
722a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
723a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId1 = createRawContactWithName(account1);
724a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
725a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
7265d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
727a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
728a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
729a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
730a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
731a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
732a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
733a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
734a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
735a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
736a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
737a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
738a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
739a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
740a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
741a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
742a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
743a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
744a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
745a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
746a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
747a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
748a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
749a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
750a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
751a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
752a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
753a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
754a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
755a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
756a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
757a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
758a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
759a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
760a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
761a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
762a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
763a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
764a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
765a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
766a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
767a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
768a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
769a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
770a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
771a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
772a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
773a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
774a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
775a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
776a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
777a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
778a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
779a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
780a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
781a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
782a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
783a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
784a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
785a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
786a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
787a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
788a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
789a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
790a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
791a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
792a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
793a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
794a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
795a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
796a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
797a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
798a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
799a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
800a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
801a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
802a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
803a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
804a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
805a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
806a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
807a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
808a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
809a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
810a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
811a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
812a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
813a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
8154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("John", "Doe");
8164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
8184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
8194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
8204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
8214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
8254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
8274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
8294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
8304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
8314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
8324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
8334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
8354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
8364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
8374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
83881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
8394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
84189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
84289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
84389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
84489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
84589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri1 = insertStructuredName(rawContactId1, "John", "Doe");
84689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
84789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri dataUri2 = insertStructuredName(rawContactId2, "Jane", "Doe");
84889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
84989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(dataUri1, account1);
85089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(dataUri2, account2);
85189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
85289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
85389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
85489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
8554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
8567d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
8573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
8584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
8594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
8604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
8614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
8624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
8634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
8654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
8664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
8684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
8694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
8704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
8744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
8753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
8764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
8774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
8784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
8794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
8804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
8814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
8824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
8834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
8844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
8854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
8864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
8874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
88848828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
8894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
8904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
8914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
892cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    public void testPhonesWithMergedContacts() {
893cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        long rawContactId1 = createRawContact();
894cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "123456789", true);
895cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
896cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        long rawContactId2 = createRawContact();
897cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "123456789", true);
898cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
899cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        ContentValues values1 = new ContentValues();
900cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "123456789");
901cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
902cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Phone.NUMBER, "123456789");
903cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
904cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        // Two results should come, since they are separate entries anyway.
905cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
906cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
9078ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Even with remove_duplicate_entries flag, we should return two results here, because
9088ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // they have different raw_contact_id-s.
9098ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Phone.CONTENT_URI.buildUpon()
9108ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
9118ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
9128ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, new ContentValues[] {values1, values1});
9138ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
914cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
915cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa                rawContactId1, rawContactId2);
916cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
917cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertAggregated(rawContactId1, rawContactId2, "123456789");
918cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
9198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Contact merge won't affect the default result of Phone Uri.
9208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
9218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
9228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // We should detect duplicates when requested.
9238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values1);
924cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    }
925cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
926904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    public void testPhonesNormalizedNumber() {
927904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final long rawContactId = createRawContact();
928904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
929904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Write both a number and a normalized number. Those should be written as-is
930904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final ContentValues values = new ContentValues();
931904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.RAW_CONTACT_ID, rawContactId);
932904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
933904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1234");
934904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "5678");
935904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.TYPE, Phone.TYPE_HOME);
936904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
937904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
938904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
939904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Ensure both can be looked up
940904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
941904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
942904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
943904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
944904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
945904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace both in an UPDATE
946904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
947904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "4321");
948904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
949904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
950904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
951904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
952904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
953904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "4321"), null, null));
954904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
955904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
956904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
957904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
958904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
959904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NUMBER ==> NORMALIZED_NUMBER will be inferred (we test that by making
960904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // sure the old manual value can not be found anymore)
961904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
962904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1-800-466-5432");
963904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
964904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
965904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
966904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1-800-466-5432"), null,
967904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
968904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
969904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
970904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
971904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NORMALIZED_NUMBER ==> call is ignored, things will be unchanged
972904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
973904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
974904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
975904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
976904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
977904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1-800-466-5432"), null,
978904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
979904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
980904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
981904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    }
982904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
9834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
984e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
985e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
986e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
987e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
988e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
989e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
990e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
991e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
992e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
993e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
994e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
995e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
996e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
997e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
998e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
999e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
1000e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
1001e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1002e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
10035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
10045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1005e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final long rawContactId2 = createRawContactWithName("Chilled", "Guacamole", ACCOUNT_2);
10062a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
100758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
100858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
10095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1010e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
10134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
10145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
10154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
10164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
10175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
10184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1019e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
10205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
10215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1022e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
10235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
10245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1025e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
10265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
102745d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
1028e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
102945d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
103058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
103158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
103258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
103358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
103458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
103558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
103658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
103758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
103858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
103958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
104058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
104158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
104258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
104358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
104458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
104558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
104658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
104758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
104858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
104958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
105058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
105158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
1052e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
1053e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
1054e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1055e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
1056e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1057e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1058e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1059e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1060e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1061e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1062e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1063e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1064e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1065e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1066e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1067e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1068e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1069e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1070e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1071e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1072e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1073e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1074e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1075e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1076e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1077e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1078e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1079e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1080e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1081e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1082e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1083e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1084e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1085e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri3, values);
1086e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1087e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
108858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1091e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1092e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1093e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1094e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1095e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1096e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1097e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1098e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1099e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
11004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
11014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1102ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1103ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1104ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
11054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1106e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1107e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1108e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1109e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1110e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1111e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1112e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1113e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1114e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1115ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
11164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1117892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
111834984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1119e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
112034984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
1121892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1122892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1123892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1124892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1125892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1126892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1127892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1128892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1129892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1130892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1131892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1132892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1133892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1134892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1135892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1136892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1137892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1138892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1139892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1140892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1141892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1142892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1143892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1144892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1145892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1146892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1147892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1148892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1149892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1150892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1151892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1152892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1153892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1154892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1155892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1156892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot1", "Tamale");
1157892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1158892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1159892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1160892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1161892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1162892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1163892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1164892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1165892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1166892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1167892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1168892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1169892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1170892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1171892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1172892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1173892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1174892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1175892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1176892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot2", "Tamale");
1177892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1178892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1179892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1180892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1181892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1182892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1183892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1184892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1185892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1186892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1187892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
11884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
11894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
119056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
119156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Checks the logic that relies on using the trailing 7-digits as a fallback for phone
119256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // number lookups.
119356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
119456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
119556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
119656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
119756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
119856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
119956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertStructuredName(rawContactId, "Senor", "Chang");
120056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
120156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
120256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
120356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
120456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
120556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
120656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
120756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
120856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
120956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
121056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with +0 prefix should also match.
121156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
121256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+097427289"), null, null));
121356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
121456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
121556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
121656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
121756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
121856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
121956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
122056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
122156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
122256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
122356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
122456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
122556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
122656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
122756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
122856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
122956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
123056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
123156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
123256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
123356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
123456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
123556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertStructuredName(rawContactId, "Senor", "Chang");
123656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
123756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
123856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
123956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
124056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
124156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
124256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
124356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
124456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
124556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
124656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
124756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
124856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
124956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
125056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
125156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
125256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
125356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1254653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1255653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1256653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1257653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1258653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1259653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1260653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1261653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1262653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1263ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
1264ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
1265ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
1266653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1267653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1268653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1269653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1270653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1271ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1272ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
1273653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1274653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1275653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1276653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1277653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1278653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1279ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1280653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1281653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1282653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1283653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1284653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1285653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1286ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1287ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
128881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1289653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1290653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1291e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
1292e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
1293e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long rawContactId1 = createRawContactWithName("Meghan", "Knox");
1294e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
1295e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
1296e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1297e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long rawContactId2 = createRawContactWithName("John", "Doe");
1298e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
1299e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
1300e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
1301e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1302e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1303e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
1304e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
1305e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
1306e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1307e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
1308e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
1309e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
1310e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
1311e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1312e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
1313e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
1314e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
1315e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
1316e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1317e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
1318e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
1319e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1320e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
1321e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
1322e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1323e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1324e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
1325e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
1326e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1327e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
13314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
13324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
13334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
13344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
13354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
13378ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
13384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
13408ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
13418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
13424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13438ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
13444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
13454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
13464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
13474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
13484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
13494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
13504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
13514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
13524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
13534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
13544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
13554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
13564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
13574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
13584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
136048828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
13614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
13628ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13638ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
13648ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
13658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
13668ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
13678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
13688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
13708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
13718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
13728ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13738ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
13748ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
13758ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
13768ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
13778ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
13788ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13798ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
13808ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13818ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
13828ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
13838ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
13848ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
13854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13875e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
13884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Hot", "Tamale");
13894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
13904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13915e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
13924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
13944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
13954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
13964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
13974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
13984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
13994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
140008768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
140108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
140208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
140308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
140408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
14054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
14075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
140847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
14095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
14105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
14115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
141247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Hot", "Tamale", ACCOUNT_2);
14135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
14145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
14155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
14165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
14175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
14185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
14195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
14205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
14215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
14225e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
14235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
14245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
14255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
14265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1427155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
14285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
14295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
14301e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
14315e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
14325e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
14335e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
14345e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
14355e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
14365e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
14377d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1438c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1439c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1440c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
1441c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1442c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1443c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1444c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1445c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1446c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1447c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1448c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1449c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1450c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1451c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1452c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1453c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v1, v2, v3 });
1454c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1455c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1456c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1457c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1458c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1459c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
1460c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1461c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1462c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1463c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1464c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1465c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1466c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1467c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1468c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1469c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1470c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1471c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1472c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
14737d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
14747d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
14757d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
14767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
14777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId1 = createRawContact(ACCOUNT_1);
14787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
14797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId2 = createRawContact(ACCOUNT_2);
14807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
14817d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
14827d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
14837d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
14847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
14857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
14887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_1.type)
14897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
14917d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
14947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_2.type)
14957d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
14977d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14987d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
14997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
15007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
15017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
15027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2 });
15037d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
15047d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
15057d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
15067d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
15077d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
15087d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
15097d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
151046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
151146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
151246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId1 = createRawContact();
15134928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
15144928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
151546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId2 = createRawContact();
15164928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
15174928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
15184928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
15194928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
152046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
152146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
152246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
152346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
152446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
152546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
152646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
152746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
152846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
152946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
153046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
153146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
153246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
153346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
153446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
153546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
153646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
153746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
153846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
153946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
154046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
154146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
154246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
154346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
154446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
154546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
15464928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
154746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
154846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // account3@email.com should be the first. account2@email.com should also be promoted as
154946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // it has same contact id.
155046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
155146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
155246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
155346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1554f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1555f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1556f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1557f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1558f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
1559f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long rawContactId1 = createRawContact();
1560f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1561f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1562f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1563f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1564f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1565f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1566f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1567f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1568f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1569f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1570f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1571f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1572f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1573f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1574f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1575f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1576f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1577f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1578f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1579f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1580f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1581f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1582f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1583f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1584f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1585f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1586f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1587f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1588f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1589f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1590f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1591f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1592f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1593f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1594f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1595f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1596f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1597f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1598f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1599f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1600f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1601f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1602f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1603f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1604f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1605f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1606f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1607f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1608f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1609f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1610f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1611f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1612f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1613f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1614f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1615f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1616f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1617f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1618f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
16194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
16204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Alice", "Nextore");
16214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
16228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
16234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
16254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
16274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
16284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
16294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
16304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
16324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
163448828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
163548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
16364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
16378ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16388ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
16398ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
16408ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
16418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
16428ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
16438ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16448ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
16458ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
16468ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
16478ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16488ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
16498ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
16508ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
16518ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
16528ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
16538ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
16548ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
16558ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16568ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
16578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
16598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
16608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
16618ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
16624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
16654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1667aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1668d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
16694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
16704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
16724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
16734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16750a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
16764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1678aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1679aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
168082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1681aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
1682ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
1683ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
1684ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
16854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1687a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
16884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
168948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1690aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1691d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1692aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
169348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
169448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
169548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
169648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
16973b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
16983b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
16997ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, nameValues);
170048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
170148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
170282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
170348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1704ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
1705ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
17064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
170748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
17083b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
170948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1710a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
17113b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
17123b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
1713a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
17147ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
17157ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
17167ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
17177ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
17187ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
17197ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
17207ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
17217ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
17227ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
1723a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1724a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1725a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1726a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
1727a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1728a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1729a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1730a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1731a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1732a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1733a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1734a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1735a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1736a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1737a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1738a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
1739a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1740a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1741a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
1742a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
1743a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
1744a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
1745a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
1746a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1747a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
1748a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
1749a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1750a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1751a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1752a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
1753a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1754a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1755a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1756a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1757a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1758a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1759a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1760a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1761a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1762a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1763a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1764a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
1765a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1766a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1767a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
1768a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
1769a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
1770a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
1771a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1772a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
1773a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
1774a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
17754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
17764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
17772f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
17782f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
17792f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
17802f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
1781ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
17824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
17832f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
17842f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
17854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
17862f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
1787d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
17884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
17894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
17904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
1791aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
1792aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
17934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
17942f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
17952f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
17962f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
17972f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
1798d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
17994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
18009dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
1801aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
1802d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
18034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
18042f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
18052f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
18062f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
18072f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
18082f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
18094928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
18102f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
18112f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
18122f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
18132f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
18142f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
18154928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
18162f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
18174928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
18182f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
18192f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
18202f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
18214928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
18222f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
18239dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
18249dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
18259dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
18262f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
18272f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
18282f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
18299dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
18309dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
18319dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Now the 4th contact has a phone number.
18329dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        insertPhoneNumber(rawContactId4, "18004664414");
18339dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
18349dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Phone only strequent should return 4th contact.
18354928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
18364928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
18374928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
18384928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
18394928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
18404928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
18414928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
18424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1843ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
18442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
18454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
18464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
184745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
184845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
184945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
185045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
185145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
185245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
185345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
185445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
185545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
185645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
185745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
185845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
185945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
186045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
186145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
1862363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
1863363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
186445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
186545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
186645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
186745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
186845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
186945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
187045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
187145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
187245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
187345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
187445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
187545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
187645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
187745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
187845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
187945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
188045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
188145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
188245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
188345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
188445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
1885363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
1886363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
1887363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1888363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
1889363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
1890363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1891363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
1892363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
1893363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
1894363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
1895363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
1896363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
1897363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
1898363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
1899363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1900363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
1901363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
1902363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1903363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
1904363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
190545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
190645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
1907ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
19084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
19094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
19104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
19114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
1912aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
1913aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
19144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
19154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
19164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
1917aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
1918aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
19194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1920ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
19214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
19224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
19234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
19244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
19254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
19264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1927ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
19284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
19294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
19304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
19314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
19324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1933ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
19344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
19354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
19364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
19373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
19383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
193936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
194036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
194124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
194224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
194336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
194436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
194524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
194636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
194724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
194824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
194924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
195024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
195124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
195236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
195336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
195436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
195536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
195636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
195736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
195836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
195936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
196036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
196136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
196236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
196324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
196424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
196536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
196636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
196736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
196836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
196924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
197024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
197136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
197236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
197336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
197436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
197524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
197624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
197724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
197824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
197924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
198024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
198124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
198224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
198324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
198436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
198536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
198636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
198736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
198824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
198924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
199024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
199124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
199224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
199324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
199424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
199536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
199636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
199736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
199836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
199924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
200024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
200124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
200224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
200324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
200424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
200524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
200624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
200724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
200836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
200936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
201036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
201124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
201224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
201336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
201436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
201536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
201636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
201736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
201824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
201924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
202036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
202136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
202236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
202336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
202436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
202524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
202624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
202724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
202824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
202924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
203024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
203124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
203224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
203324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
203424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
203524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
203624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
203724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
203836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
203936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
204036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
204136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
204224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
204324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
204424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
204524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
204624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
204724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
204824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
204936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
205036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
205136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
205236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
205324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
205424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
205524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
205624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
205724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
205824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
205924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
206024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
206124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
206224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
206324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
206424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
206524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
206624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
206724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
206824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
206924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
207024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
207124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
207224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
207324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
207424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
207524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
207624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
207724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
207824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
207924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
20806ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
20816ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
20826ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
20836ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20846ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
20856ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long rawContactId = createRawContactWithName("Domo", "Arigato");
20866ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
20876ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
20886ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
20896ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
20906ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20916ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
20926ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
20936ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
20946ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
20956ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
20966ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
20976ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20986ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
20996ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
21006ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
21016ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
21025d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
210324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
210424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
210524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
210624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
210724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
210824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
210924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
211024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
21115d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
211224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
21135d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
21145d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
211524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
211624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
211724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
211824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
211924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
212024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
212124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
212224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
212324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
212424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
212524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
212624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
212724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
212824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
212924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
213024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
213124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
213324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
213424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
213624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
213724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
213824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
213924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
214024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
214124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
214224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
214324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
214424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
214524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
214624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
214724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
214824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
214924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
215024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
215124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
215224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
215324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
215424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
215524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
215624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
215724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
215824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
215924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
216024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
216124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
216224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
216324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
216424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
216524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
216624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
216724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
216824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
216924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
217024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
217124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
217224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
217324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
217424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
217524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
217624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
217724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
217824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
217924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
218024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
218124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
218224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
218324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
218424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
218524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
218624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
218724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
218824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
218924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
219024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
219124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
219224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
219324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
219424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
219524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
219624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
219724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
219824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
219924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
220024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
220124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
220224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
220324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
220424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
220524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
220624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
220724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
220824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
220924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
221024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
221124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
221224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
221324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
221424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
221524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
2216cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
2217cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
2218cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
2219cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
2220cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
2221cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
2222cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
2223cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2224cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
2225cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
2226cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2227a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
2228a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
2229a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
2230a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2231a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
2232a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
2233a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
2234a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Uri profileUri = maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI, account)
2235a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
2236a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
2237a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
2238a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
2239a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2240a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
2241a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
2242a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
2243a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
224485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
224585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
224685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
2247c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
224885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
224985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
225085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
225185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
225285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
225385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
225485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
2255c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
225685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
225785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
225885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
225985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
22600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
226119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
226219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
226319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
226419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
226519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
226619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
226719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
226819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
226919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
227019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
227119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
227219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
227382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
2274aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
2275aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
227682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
2277aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
2278aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
227919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
228019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
228182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
228219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
2283a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
2284a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
228519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
228619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
228719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
228819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
228919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
229082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
22910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
229219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
229319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
229419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2295a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
229619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
229719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
229819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
229919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
230019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
230182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
23020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
230319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
230419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
230519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2306a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
230719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
230819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
230919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
231019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
231119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
231289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
231389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
231489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
231589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
231689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
231789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
231889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
231989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
232089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
232189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
232289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
232389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
232489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
23253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
23263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
23273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
23283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
23293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
23309d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
23313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
23323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
23333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
23343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
23353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
23363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
23373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
23383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
233994021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
23403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
23413cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
23423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
23433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
23443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
23453cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
23463cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
234773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
23483cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
23493cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
23503cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
2351f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
2352f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2353f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2354f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2355f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
2356f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2357f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
2358f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2359f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2360f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
2361f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2362f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2363f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2364f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2365f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
2366f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2367f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
2368f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2369f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2370f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
2371f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2372f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2373f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2374f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
2375f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
2376f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
2377f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
2378f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
2379f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
2380f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
2381f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
2382f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
2383f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
2384f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
2385f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2386f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
23875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
23885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
23895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
23905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
23925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
23935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
23945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
23965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
23975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
23985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
23995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
24015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
24025f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
24035f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24045f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
24055f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
24065f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
24075f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24085f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
24095f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
24105f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
24115f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24125f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
24135f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
24145f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24155f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
24165f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
24175f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
24185f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24195f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
24205f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
24215f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
24225f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24235f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
24245f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
24255f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
24265f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
24275f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
24285f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
24295f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
24305f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24315f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
24325f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
24335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
24345f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24355f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
24365f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
24375f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
24385f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24395f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
24405f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
24415f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
24425f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
24435f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
24445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
24455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
2446f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
2447f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
2448f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
2449f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
2450f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
2451f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
2452f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2453f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
2454f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
2455f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId0 = createRawContactWithName("firstName0", "lastName0");
2456f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2457f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId1 = createRawContactWithName("firstName1", "lastName1");
2458f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
2459f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
2460f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2461f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId2 = createRawContactWithName("firstName2", "lastName2");
2462f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
2463f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
2464f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
2465f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2466f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2467f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
2468f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
2469f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
2470f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
2471f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
2472f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
2473f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
2474f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2475f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2476f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
2477f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
2478f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
2479f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
2480f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
2481f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
2482f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
2483f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2484f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
2485f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
2486f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
2487f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
2488f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
2489f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
2490f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
2491f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
2492f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2493f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2494f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2495f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
2496f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
2497f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
2498f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
2499f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2500f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2501f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2502f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
2503f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId3 = createRawContactWithName("firstName3", "lastName3");
2504f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
2505f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
2506f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
2507f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
2508f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2509f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2510f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2511f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
251218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
251318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
251418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
251518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
251618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
251718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
251818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
251918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
252018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
252118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
252218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
252318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2524f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
2525f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2526f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
2527f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
2528f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
252918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
253018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
253118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
253218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
253318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
253418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2535f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
2536f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
2537f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
2538f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
2539f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
2540f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
2541f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
2542f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
254318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
254418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
254518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
254618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
254718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
254818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2549f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
255023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
255123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
255223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
255323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
255423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
255523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
255623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
255723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
255823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
255923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
256023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
256123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
2562f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2563f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
256489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
256589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
256689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
2567f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
256889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
256989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
2570f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
257189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
257289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
2573f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
2574f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
2575f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
2576f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
2577f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
257889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
257989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
2580f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
258189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
2582f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
258389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
2584f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
2585f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
2586f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
2587f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
2588f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
2589f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
2590f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
2591f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
2592f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
2593f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
2594f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
25950e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
25960e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
25970e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
25980e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
25990e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
26000e21a867a572679d64d79041eb574d13665178d4Dave Santoro
26010e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
26020e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
26030e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
26040e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
26050e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
260689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
260789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
26084097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
2609d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
26104097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
26114097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
26125ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
26134097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
261417a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
26154097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
26164097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
261767c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
261867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        long rawContactId = createRawContact();
261967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
262067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
262167c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
262267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
262367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        insertStructuredName(rawContactId, values);
262417a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
262567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
262667c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
26274097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
2628d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
26294097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
26304097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
26314097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
26325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
26334097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
26345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
26354097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
26364097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
26375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
26385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        final long rawContactId = createRawContact(null);
26395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
26415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
26425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
26435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
26445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
26455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
26465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
26475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
265055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
265155e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
26525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
26535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
26555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
26565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
26585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
26595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
266255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
266355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
26645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
26655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
26675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
26685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
26705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
26715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
26725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
26745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
26755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
26785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // Only run this test when Chinese collation is supported
26805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
26815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
26825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
26835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
26855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
26875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
26885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
26895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
26925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
26935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
26945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
26955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26964cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26974cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
27005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
27015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
27045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
27055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
27065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
27075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
27084cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
27094cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
27105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
27125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
27135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
27145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
27165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
27175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
27185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
27205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
27215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
27235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
27245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
27255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
27265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
27295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
27305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
27315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
27325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
27335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
27345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
27355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
27375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
27385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
27415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
27425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
27435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
27445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
27455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
27465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
27475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
27495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
27505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
27515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
27535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
27545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
27555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
275625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
275725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId1 = createRawContact();
275825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
275925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
276025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId2 = createRawContact();
276125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
276225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
27630c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
27640c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
276525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
276625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
276725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
276825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertStructuredName(rawContactId2, "Potato", "Head");
276925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
277025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
277181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
277225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
277325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
277401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
277501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long rawContactId = createRawContact();
277601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2777a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
277801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
277901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
278001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
278101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
278201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
278301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
278401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
278501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
278601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
278701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
278801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
278901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
279001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2791a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
2792a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2793a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
27945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
279501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
279601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2797a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
2798a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
2799a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
2800a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
2801a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
2802a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2803a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
2804a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
2805a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
2806a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertStructuredName(rawContactId, values);
28075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
28085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
28095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
28115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
28125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
28135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
28145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
28165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
28185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
28205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
28215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
28225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
28245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
28265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
28275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
28305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
28315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
28325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
28335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
28345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
28355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
28365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
28385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
28395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
28405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
28415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
28435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
28455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
28475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
28485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
28495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
28525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
28535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
28545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
28555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
28565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
28575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
28585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
28600b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        boolean hasChineseCollator = false;
28610b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        final Locale locale[] = Collator.getAvailableLocales();
28620b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        for (int i = 0; i < locale.length; i++) {
28630b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            if (locale[i].equals(Locale.CHINA)) {
28640b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                hasChineseCollator = true;
28650b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                break;
28660b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            }
28670b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
28680b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
28690b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        if (!hasChineseCollator) {
28700b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
28710b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
28720b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
28735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
28745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
28755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
28765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
28785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
28805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
28825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
28835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
28865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
28875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
28884cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
28894cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
28905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
289101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
289201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
289331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
289431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long rawContactId = createRawContact();
289531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
289631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
289731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
289831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
289931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
290031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
290131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
290231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
290331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
290431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
290531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
290631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
290731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
290831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
290931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
291031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
291131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
291231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
291331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
291431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
291531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
291631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
291731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
291831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
291931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
292031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
292131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
292231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
292331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
292431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
292531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
292631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
292731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
292831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
292931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
293031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
293131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
293231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
293331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
293431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
293531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
293631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
293731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
293831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
293931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
294031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
2941a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
2942a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, filter);
2943a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
2944a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2945a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2946916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
2947916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2948916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2949916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2950916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
2951916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
2952916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2953916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2954916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2955916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
29569c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
2957916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
2958916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2959916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
2960916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
2961916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2962916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2963916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
2964916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
2965916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2966916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2967916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
2968916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2969916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29706f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
2971916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2972916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2973916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
29743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "engineer, [acmecorp]");
2975916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2976916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2977916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2978916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
2979916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContact();
2980916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2981916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2982916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "John", "Doe");
2984916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2985916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29866f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
2987916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2988916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2989916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
29903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[acme@corp.com]");
2991916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2992916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2993916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2994fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
2995fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
2996fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
2997fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
2998fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
2999fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
3000fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
3001fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
3002fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
3003fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
3004fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
3005fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
3006fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
30073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
30083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
30113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
30133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
30143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
30163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
30173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
30183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
30213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
30233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
30253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
30273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
30293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
30313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
30323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
30333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30356f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
30366f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
30376f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
30386f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
30396f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
30406f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
30416f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
30426f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
30436f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
3044916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
3045916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
3046916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3047916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3048916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3049916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
3050916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
30516f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
3052916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3053916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3054916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
305530cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        values.put(SearchSnippetColumns.SNIPPET, "[Incredible]");
3056916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3057916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3058916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
30593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
30603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
30633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
30643716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30706f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
30716f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("john", true), emptySnippet);
30723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
30753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
30783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
30793716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30803716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30813716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30823716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30856f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
30863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30873716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
30893716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30913716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
30923716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
30933716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
30943716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
30953716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
30963716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
30973716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30983716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30993716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
31003716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
31013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
31023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31036f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("aperture", true), emptySnippet);
31043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
31053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
31073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
31083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
31093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
31103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
31113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
31133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
31143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
31153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
31163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31176f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("860", true), emptySnippet);
31183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
31193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
31213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
31223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
31233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
31243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
31253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
31273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
31283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
31293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
31303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
31316f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
31323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
31333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
3134dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
3135dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long rawContactId = createRawContact();
3136dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, "Slinky", "Dog");
3137dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3138dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3139dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3140dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3141dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
3142dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3143dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
3144dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
3145dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3146dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3147dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
3148dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3149dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
3150dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3151dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3152dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
3153dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3154dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
3155dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3156dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3157dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
3158dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
3159dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3160d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
3161d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
3162d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
3163d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3164d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
3165d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
3166d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
3167d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
3168d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
3169d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3170d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
3171d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
3172d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
3173d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3174d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
3175d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
3176d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
3177d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
3178c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
3179d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3180d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3181d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3182d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3183d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3184d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
3185d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3186d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3187d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3188d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
3189c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
3190d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3191d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3192d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
3193d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
319481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
31958c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
31968c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
31978c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
31988c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
3199d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3200d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3201d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
32023cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("a", "b");
3203d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3204d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3205d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
32063cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("c", "d");
3207d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3208d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
3209d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3210d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
32110c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
32120c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3213d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3214d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
3215d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
3216d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3217d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3218d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
32193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("e", "f");
3220d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3221d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
3222d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
32233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("g", "h");
3224d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3225d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
3226d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3227d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
32280c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
32290c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3230d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3231d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
32320c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
3233d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3234d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3235d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
32363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("i", "j");
3237d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3238d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3239d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
32403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("k", "l");
3241d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3242d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
3243d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3244d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
32450c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
32460c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3247d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3248d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
32490c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
32500c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3251d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
32523cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
3253d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
3254d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3255d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
325682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
32574dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        long rawContactId = createRawContact();
32580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
32590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
32600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
32620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
32640a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
32650a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
32660a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
32670a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
32680a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
32690a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
32700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
32710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
32720a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
32740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32750a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
32760a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32770a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
32780a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
32790a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
32820a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
32830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
32840a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
32850a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
32860a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
32870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32880a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
32890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32900a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
32930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
32940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
32950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
32960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
32970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
32980a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
33000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
33010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
33020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
33030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
33040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
33050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
33060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
33070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
33080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
33100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
33110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
33120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
33130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
33150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
33160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
33170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
33180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
33190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
33210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
33230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
33240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
33250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
33260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
33280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
33290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
33300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
33310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
33324dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
33334dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
333482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
33354dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
33364dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
3337aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3338aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
33394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
33404dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
3341aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
3342d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
33434dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
33444dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
3345aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
3346aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
33474dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
33484dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
3349aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
3350aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
33514dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
335282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
335382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
33540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
335582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
33564dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
335782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
33584dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
335982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
33604dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
336182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
33624dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
33634dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
3364bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3365bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3366bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3367bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3368bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
336982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
33700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3371bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3372bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
3373bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
337482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
3375bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long rawContactId = createRawContact();
3376bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3377bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3378bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3379bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3380bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3381bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
338282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
338382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
3384bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3385bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3386aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
3387aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3388aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
3389aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
339082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
3391aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3392aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
339382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
3394bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
339582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
339682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3397bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3398bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
33999705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
34009705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
34019705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
34029705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
34039705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
34049705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
34059705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
34069705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
34079705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
34089705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
34099705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
34109705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
34119705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
34129705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
34139705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
34149705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
34159705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
34169705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
34179705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
34189705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
34199705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
34209705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
34219705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
34229705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
34239705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
34249705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
34259705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
34269705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
34279705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
34289705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
34299705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
34309705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
34319705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
34329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
34339705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
34349705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
34359705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
34369705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
34379705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
34389705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
34399705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
34409705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
34419705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
34429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
344382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
34449705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
344582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
3446a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3447a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
3448a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3449093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
3450093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long rawContactId = createRawContact();
3451093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3452093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3453093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3454093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3455093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3456093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
3457093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
3458093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3459093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
3460093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
3461093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3462093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
3463093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3464093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3465093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3466093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
3467093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
3468093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
3469093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
3470093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3471093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
3472093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
3473093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3474093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3475093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
3476093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
347782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
3478a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long rawContactId = createRawContact();
3479a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3480a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
3481a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3482a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3483a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3484aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
34855d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3486aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
34875d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3488aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
34895d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3490a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3491a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
3492a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
349382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
349482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3495bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
34964dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
34974dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
349882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
349982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
35004dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
350182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
350282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
3503a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
350482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
35054dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
35064dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
35074dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
35083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
35093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
35113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
35123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
35143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
35153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
35163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
35173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
35183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
35193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
35223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
35243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
35263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
35273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
35283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
35293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
35303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
35313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
35343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
35363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
35373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
35393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
35403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
35413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
35423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
35433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
35443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
35473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
35493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
35503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
35523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
35533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
35543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
35553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
35563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
35573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
35583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
35593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
35623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
35653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
35663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
35693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
35723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
35763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
35783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
35793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
35803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
35823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
35833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
35843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
35873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
35903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
35913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
35953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
35963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
35983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
35993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
36003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
36023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
36033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
36043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
36073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
36093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
36113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
36123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
36133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
36153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
36166802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
36183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
36193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
36213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
36223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
36233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
36263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
36293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
36303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
36313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
36323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
36343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
36353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
36363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
36373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
36393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
36403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
36416802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
36443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
36456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
36466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
36473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
36486802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
36513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
36523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
36533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
36543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
36573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
36603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
36613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
36623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
36633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
36653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
36663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
36673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
36683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
36703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
36713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
36723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
36736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
36763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
36776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
36786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
36793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
36803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
36816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
36843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
36853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
36863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
36873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
36883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
36893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
36903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
36923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
36933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
36943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
36953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
36963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
36973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
36983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
37013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
37033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
37043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
37063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
37083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
37103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
37113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
37133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
37143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
37153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
37163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
37173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
37183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
37193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
37233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
37263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
37273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
37283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
37293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
37303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
37333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
37363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
37383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
37403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
37413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
37423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
37433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
37443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
37453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
37473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
37493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
37503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
37513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
37523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
37533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
37543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
37553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
37563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
37573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
37583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
37593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
37603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
37613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
37643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
37653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
37683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
37713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
37733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
37743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
37753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
37763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
37773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
37783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
37793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
37823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
37833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
37843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
37853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
37863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
37893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
37913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
37933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
37943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
37963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
37973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
37983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
37993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
38003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
38013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
38023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
38033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
38043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
38053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
38063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
38073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
38083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
38093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
38113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
38123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
38133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
38143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
38153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
38163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
38173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
38183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
38193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
38203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
38213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
38223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
38243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
38256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
38266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
38273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
38283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
38293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
38306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
38316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
38326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
38336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
3834c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                EvenMoreAsserts.assertImageRawData(
3835c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                        expectedPhotoBytes, mResolver.openInputStream(Uri.parse(photoUri)));
38366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
38373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
38383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
38393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
38403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
38433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
38453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
38503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
38513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
38523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
38533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
38543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
38553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
38583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
38633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
38643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
38653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
38663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
38673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
38683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
38713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
38733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
38783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
38793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
38803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
38826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
38833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
38843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
38853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
38863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
38873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
38883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
38893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
38906802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
38913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
38926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
38936802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
38946802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
3895c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
3896c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
38976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
38983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
39013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
39033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
39043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
39053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
39063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
39073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
39083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
39106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
39116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
39123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
39133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
39143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
39153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
39163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
39176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
39183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
39196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
39206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
39216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
3922c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
3923c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
39246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
39253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
39283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
39303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
39323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
39333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
39343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
39363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
39373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
39383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
39403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
39413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
39423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
39443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
39453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
39463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
39473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
39503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
39523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
39533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
39553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
39563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
39573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
39593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
39603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
39613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
39633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
39643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
39653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
39663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
39693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
39713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
39733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
39743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
39753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
39763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
39773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
39783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
39793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
39803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
39813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
39823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
39843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
39853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
39863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
39873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
39883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
39893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
39903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
39913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
39923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
39953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
39973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
39983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
39993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
40003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
40016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
40023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
40033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
40043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
40053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
40063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
40073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
40083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
40093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
40103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
401182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
401282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        long rawContactId = createRawContact(mAccount);
401382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
401482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
401582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
401682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
401782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
401882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
401982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
402082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
402182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
402282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
402382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
402482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
402582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
402682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
40273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
40283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
40293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
40303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
40313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
40323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
40336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
40346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
40356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
40376802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
40396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
40406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
40416802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
40426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
40436802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
40446802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
40456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
40476802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
40484747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
4049d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
4050d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
4051d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
4052d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
4053d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
4054d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4055d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
4056d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4057d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
4058d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
4059d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
4060d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
4061d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
4062d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
4063d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4064d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
4065d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
4066d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
4067d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4068d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
4069d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
40704747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
40716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
40726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
40736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
40746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
40756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
40766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
40786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
40806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
40816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
40826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
40836802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
40846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
40856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
40866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
40886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
40896802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
40906802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
40926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
40934747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
40946802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
40956802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
40966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
40976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
40986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
40996802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
410036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
410136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
410236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
410336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
410436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
410536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
410636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
410736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
410836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
410936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
411036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
411136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
411236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
411336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
411436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
411536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
411636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
411736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
411836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
411936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
412036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
412136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
412236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
412336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
412436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
412536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
412636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
412736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
412836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
412936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
413036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
413136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
413236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
413336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
413436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
413536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
413636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
413736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
413836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
413936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
414036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
414136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
414236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
414336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
414436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
414536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
414636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
414736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
414836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
414936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
415036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
415136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
415236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
415336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
415436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
415536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
415636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
415736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
415836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
415936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
416036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
416136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
416236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
416336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
416436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
416536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
416636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
416736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
416836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
416936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
417036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
417136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
417236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
417336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
417436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
417536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
417636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
417736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
417836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
417936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
418036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
418136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
418236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
418336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
418436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
418536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
418636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
418736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
418836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
418936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
419036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
419136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
419236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
419336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
419436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
419536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
419636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
419736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
419836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
419936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
420036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
420136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
420236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
420336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
420436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
420536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
420636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
420736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
420836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
420936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
421036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
421136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
421236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
421336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
421436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
421536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
421636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
421736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
421836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
421936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
422036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
422136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
422236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
422336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
422436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
422536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
422636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
422736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
422836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
422936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
423036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
423136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
423236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
423336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
423436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
423536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
423636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
423736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
423836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
423936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
424036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
424136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
424236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
424336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
424436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
424536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
424636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
424736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
424836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
424936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
425036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
425136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
425236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
425336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
425436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
425536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
425636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
425736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
425836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
425936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
42603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
42613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
42623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
42633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
42643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
42653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
42663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
42693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
42703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
42716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
42726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
42733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
42743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
427682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
4277bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
4278bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
4279bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4280d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact();
42814dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
4282bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4283aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
4284aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4285aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
4286aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4287aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
4288aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4289bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4290af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
429182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
42924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
4293bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4294bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
429582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
429682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
42970265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
4298bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
4299bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4300d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
4301d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
4302d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
4303d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
4304d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
4305d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
4306d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
4307d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4308d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4309d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
4310d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
43118c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
43128c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
43138c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
43148c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
43158c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
43168c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
43178c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
43188c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
43198c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
43208c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
43218c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
43228c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
43238c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
4324d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4325d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4326d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
4327d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
4328d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
4329d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
4330d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
4331d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
4332d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
4333d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
4334d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
4335d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
4336d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
4337d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
4338d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
4339d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
43409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
43410be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
43420be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
43430be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
43440be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43450be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
43460be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
43470be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43480be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
43490be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
43500be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43510be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
43520be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
43530be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43540be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
43550be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
43560be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43570be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
43580be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
43590be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43600be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
43610be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
43620be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
43630be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43640be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
43650be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
43660be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
43670be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
43680be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43690db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
43700db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
43710db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
43720db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
43730db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
43740db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
43750db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
43760db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43770db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
43780db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
43790db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
43800db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
43810db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
43820db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
43830db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43840db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
43850db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43860db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
43870db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
43880db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
43890db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
43900db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
43910db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
43920db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43930db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
43940db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
43950db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
43960db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
43970db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
43980db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
43990db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
44000db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
4401a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
44029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
44039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
44049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
44069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
44079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c0");
44093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
44103cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
44113cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
44129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
4413226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c1 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c1");
44149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
44159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
44169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
44179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
44189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
4419226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c2 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c2");
44209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
44219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
44229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
44239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long c3 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c3");
44259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
44269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
44279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
44289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
442962318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
443062318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount), null,
443162318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
44329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
44339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
44349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
44356cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
44369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
44379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
44389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
44399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
44409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
44419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
44429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
44439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
44449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
44459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
44469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
44479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
44489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
44499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
44509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
44519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
44529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
44546cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
44559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
44569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
44579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
44589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
44599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
44609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
44619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
44629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
44639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
44649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
44659261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
44669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
44679261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
44696cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
44709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
44719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
44729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
44739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
44749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
44759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
44769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
44779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
44789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
44799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
44809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
44819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
44829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
44843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
44859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
448620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
448720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
4488d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
448920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
449020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
44915ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
449220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
449320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
449420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
449520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
449620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
449720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
449820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
449920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
450020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
450120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
450220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
450320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
450420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
450520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
450620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
450720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
450820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
450920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
451020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
451120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
451220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
451381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
451420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
451520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
451620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
451720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
451820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
451920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
452020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
452120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
452220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
452320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
452420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
452520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
452620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
452720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
452820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
452920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
453020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
453120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
453220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
453320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
45345ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
453520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
453681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
453770b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
453820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
453920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
45405ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
454120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
454220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
45435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
454433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
454581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
454633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
454720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
454889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
454989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
455089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
455189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
455289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
455389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
455489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
455589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
455689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
455789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
455889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
455989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
456089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
456189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
456289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
456389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
456489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
456589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
456689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
4567373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
4568e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId = createRawContact(mAccount);
45695ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
457033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
45714dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
457282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4573aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4574aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4575a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4576a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
457733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
457833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
457982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
45804dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
458133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
458233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
458333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
45845870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
458581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
458633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
4587e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
458833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
458933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
459033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
459133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
459282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
45934dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
4594a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
459581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
4596a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
4597a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4598a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
4599e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId1 = createRawContactWithName(mAccount);
4600e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId2 = createRawContactWithName(mAccount);
460147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
460247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
4603a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4604a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4605a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4606a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
4607e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
4608a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
4609a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
4610a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
461120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
46121fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
46135f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
4614e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        long rawContactId = createRawContact(mAccount);
4615e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
4616e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4617e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
461882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4619aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4620aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4621e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
4622e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
462382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
4624e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
4625e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4626e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
4627e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
4628e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4629e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
4630e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
4631e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
46325f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
46335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
4634e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
46355870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
4636e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4637e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
4638e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
4639e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4640e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
4641e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
4642e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
46435f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
46445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
46455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
46475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
46485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
46505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        long rawContactId = createRawContact(mAccount);
46515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
46525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46535f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
46545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
46555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
46565f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
46575f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
46585f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46595f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
46605f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46615f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
46625f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
46635f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
46645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
46655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
4666e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
46675870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
4668e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
4669e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
46709ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
46719ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
46729ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
46739ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
46749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
46759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
46769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_1 = Sets.newHashSet(ACCOUNT_1);
46779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_2 = Sets.newHashSet(ACCOUNT_2);
46789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(ACCOUNT_1, ACCOUNT_2);
46799ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46809ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
46819ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_1 = Sets.newHashSet(ACCOUNT_1);
46829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_2 = Sets.newHashSet(ACCOUNT_2);
46839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(ACCOUNT_2, ACCOUNT_1);
46849ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
46869ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
46879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
46889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
46919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
46929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
46939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
46969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
46979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
46989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
47019ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
47029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
47039ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
47049ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47059ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
47069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
47079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
47089ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
47099ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
47109ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
47119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47129ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
47139ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
47149ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
47159ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47169ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
47179ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
47189ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
47199ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
47209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
47219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
47229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
47249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_1 = new Account[] {ACCOUNT_1};
47259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_2 = new Account[] {ACCOUNT_2};
47269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_1_2 = new Account[] {ACCOUNT_1, ACCOUNT_2};
47279ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_2_1 = new Account[] {ACCOUNT_2, ACCOUNT_1};
47289ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47299ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
47309ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
47329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
47339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
47349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
47369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
47389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
47399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
47409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
47419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
47429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
47439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
47449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
47469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
47489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
47499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
47509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
47529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
47549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
47559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
47569ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47579ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
47589ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47599ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
47609ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
47619ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47629ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
47639ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
47649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
47659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
47669ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
4767627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
476870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
476970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
477070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        long rawContactId3 = createRawContactWithName("James", "Sullivan");
477170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
4772627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
4773743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
477470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
477570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4776bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
4777743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
4778743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
4779dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
4780dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
478170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
4782743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
4783743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
4784743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId2 = createRawContact(mAccountTwo);
4785743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
4786743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
4787743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4788aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4789aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4790743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
4791bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
4792743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
4793627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
479482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
479570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
479670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
479770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
479833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
479933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
480033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4801bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
480233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
480333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
480433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", readOnlyAccount);
480533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
480633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("john", "doe", mAccount);
480733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
480833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
480933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
481033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
481133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
481233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
481333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
481433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
481533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
481633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
481733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
481833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
481933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
482033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
482133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
482233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
482333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4824bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
482533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
482633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
482733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
482833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
482933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
483033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
483133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
483233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
483333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
483433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
483533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
483633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
483733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
483833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4839c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
4840c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
4841c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
4842c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4843c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
4844c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
4845c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4846c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
4847c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedRawContactId = createRawContactWithName(doomedAccount);
4848c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
4849c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
4850c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
4851c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
4852c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
4853c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4854c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
4855c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeRawContactId = createRawContactWithName(safeAccount);
4856c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
4857c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
4858c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
4859c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
4860c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
4861c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
4862c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4863c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
4864c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
4865c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
4866c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4867c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
4868c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
4869c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
4870c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
4871c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
4872c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
4873c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4874c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
4875c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
4876c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
4877c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
4878c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
4879c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
4880c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4881cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
488247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", ACCOUNT_1);
488347fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("John", "Doe", ACCOUNT_2);
4884cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4885cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4886cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4887cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
4888cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4889cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
4890cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4891cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
4892cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4893cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
4894cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
489573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
489673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
489773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
489873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
489973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri uri = insertStructuredName(rawContactId, "John", "Doe");
490073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
4901e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
490273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
490373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
490473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
490573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
49065870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
490773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
490881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
49091fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
49101fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
491161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
4912d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
4913d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
491473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
49151fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
49161fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
49171fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
49181fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
49191fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
492061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
4921c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
492261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
49231fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
49241fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
49251fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
49261fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
492781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
49281fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
492961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
493061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
493181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
49321fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
49331fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
493461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
49351fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
493661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
493761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
493861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
49391fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
494081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
49411fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
49421fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
494361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
49441fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
494561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
49461fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
494781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
49481fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
49491fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
495061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
49511fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
495261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
495361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
495461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
495561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
495661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
495761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
49581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
495961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
49601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
49611fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
49621fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
49631fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
49641fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
49651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
49661fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
496761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
496861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
49691fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
497061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
49711fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
497261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
497361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
497461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
497561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
49765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
497761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
497881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
497961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
498061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
49811fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
49824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
49839fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
49849fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
49859fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
49869fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49879fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
49889fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49899fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
49909fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
49919fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
49929fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49939fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
49949fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
49959fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
49969fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49979fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
49989fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
49999fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
50009fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
50019fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
50029fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
50039fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
50049fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
50059fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
50069fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
50079fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
50089fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
500960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
501060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
501160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
501260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
501360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
501460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
501560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
501660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
501760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
501860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
501960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
502060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
502160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
502260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
502360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
502460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
502560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
502660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
502760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
502860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
502960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
503060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
503160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
503260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
503360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
503460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
5035074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
5036074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
5037074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
5038074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
5039074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
5040f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5041f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5042f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
5043f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
5044f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5045074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
50463d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
50473d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
5048f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
5049074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
5050074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
5051bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
5052bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long rawContactId = createRawContact();
5053bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
5054bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5055bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
5056bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
5057bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5058bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
5059bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5060bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
5061bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
5062bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5063bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
5064bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5065bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
5066bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
5067bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
5068bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
5069bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
5070bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5071bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
5072c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5073c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithId));
5074c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5075c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
5076bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
5077bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5078ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
5079e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov        long rawContactId = createRawContact();
5080f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5081f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5082f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
5083f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
5084f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
5085e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
5086c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(loadTestPhoto(PhotoSize.DISPLAY_PHOTO),
5087f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5088c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(loadTestPhoto(PhotoSize.THUMBNAIL),
5089f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
5090ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
5091ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
5092732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
5093732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId1 = createRawContact(new Account("a", "a"));
5094f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
5095732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
5096732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5097732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId2 = createRawContact(new Account("b", "b"));
5098f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
5099732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
5100732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5101732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5102732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5103732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5104732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5105732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5107f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5108f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
5109f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
5110f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5111732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5112f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
5113732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5114732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
5115732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5116732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5117732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
5118732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
5119732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
5120732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5121732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5122732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5123732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5124732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5125732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
5126732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5127732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
5128732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5129732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
5130732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
51318e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
51328e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
51338e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
51348e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
51358e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
51368e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51378e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
51388e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
51398e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51408e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
51418e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
51428e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
51438e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
51448e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
51458e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
51468e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5147155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
51488e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51498e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
51508e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
51518e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
515281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
51538e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
51558e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
51568e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
51578e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
51597d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
51607d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
51617d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
51627d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
51637d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51647d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
51657d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
51667d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
51677d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
51687d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51697d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
51707d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
51717d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
51727d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
51737d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
51747d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
51757d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51767d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
51777d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51787d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
51797d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
51807d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
51817d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
51827d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
51837d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
51847d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51857d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
51864e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
51877d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
51884e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
5189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
51900265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
51917d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
51927d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
5193f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
5194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5195f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5196f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5197f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
5198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5200c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5201f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5202f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5203f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5204f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5205f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
5206f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5207f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5208f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5209f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5210f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5211f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5212f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5213c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5214f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5215f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5216f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5217f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5218f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
5219f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5220f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5224f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5227c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5231f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
5233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
5236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5238c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5243f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
5244f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5245f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5246f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5247f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5248f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
5249f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5250f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5251f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5252c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5253f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5254f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5255f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5256f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5257f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
5258f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5259f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5260f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5261f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
5262f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5263f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
5264f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
5265f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5266f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5267f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5268f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5269f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
5270f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5271f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5272f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5273f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
5274f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5275f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
5276f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
5277f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
5278f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5279f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5280f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
5281f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5282f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5283f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5284f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
5285f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
5286f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5287f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5288f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5289f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5290f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5291f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
5292f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5293f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5294f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5295f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
5296f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5297f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
5298f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
5299f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5300f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
5301f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
5302f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5303f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
5304c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5305f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
5306f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5307f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5308f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5309c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
5310f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5311f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5312f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5313f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
5314c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
5315c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
5316f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5317f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
5318c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
5319f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5320f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5321c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
5322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5323f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
5324c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
5325c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
5326c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
5327c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
5328c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
5329c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5330c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
5331c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
5332c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5333f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
5334f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5335f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5336f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5337f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
5338c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
5339f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5340f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
5341c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5342f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
5343f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5344c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5345f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
5346f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
5347f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5348f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5349c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
5350f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5351f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5352f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5353f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
5354f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
5355f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
5356f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
5357f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5358f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
5359f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
5360f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5361f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
5362f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
5363f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5364f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5365c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
5366c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5367c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
5368c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
5369f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5370f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
5371f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
5372f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
5373f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
5374f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5375f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
5376f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
5377f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5378f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5379c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5380f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
5381f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
5382c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5383f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
5384f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
5385f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5386f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5387f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5388c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
5389c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
5390c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
5391c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
5392c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
5393c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
5394c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
5395c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
5396c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
5397c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
5398c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
5399c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
5400c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
5401c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
5402c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
5403c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
5404c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
5405c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5406f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
5407f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
5408f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
5409f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
5410f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
5411f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5412f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5413f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
5414f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
5415c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
5416f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5417f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
5418f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
5419f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5420f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
5421f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId1 = createRawContactWithName();
5422f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
5423f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
5424f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
5425f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
5426f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5427f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5428f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId2 = createRawContactWithName();
5429f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
5430f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
5431f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
5432f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
5433f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5434f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5435f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
5436f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
5437f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
5438f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
5439f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
5440f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
5441f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
5442f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
5443f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
5444f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5445f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5446f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
5447f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
5448f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId3 = createRawContactWithName();
5449f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
5450f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
5451f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
5452f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
5453f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
5454f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
5455f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
5456f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
5457f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
5458f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5459c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
5460c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
5461c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
5462c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long rawContactId4 = createRawContactWithName(socialAccount);
5463c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
5464c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
5465c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
5466c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
5467c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
5468c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
5469c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
5470c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
5471c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
5472f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
5473f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
5474f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
5475f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5476f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
5477f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
5478f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5479f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
5480f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5481f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
5482f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
5483f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
5484f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5485f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5486f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
5487f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
5488f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
5489f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5490f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
5491f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5492f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
5493f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
5494f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
5495f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5496f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5497f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
5498f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
5499c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
5500c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
5501c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
5502c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
5503c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
5504c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
5505f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5506f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5507d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
5508d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
5509d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
5510d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5511d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
5512d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.switchToProfileMode();
5513d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
5514d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5515d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
5516d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
5517d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
5518d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
5519d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
5520d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
5521d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
5522d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
5523d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
5524d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
5525d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
5526d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
5527d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5528d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
5529d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
5530d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
5531d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
5532d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
5533d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
5534d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
5535d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
5536d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
5537d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5538d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
5539d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
5540d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
5541d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5542d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
5543d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.switchToProfileMode();
5544d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
5545d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5546d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
5547d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5548d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
5549d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
5550d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
5551d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
5552d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
5553d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5554d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
5555d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
5556d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
5557d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
5558d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5559d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
5560d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5561f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
5562f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5563f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5564f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5565f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5566f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
5567f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5568f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
5569f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
5570f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5571f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
5572f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
5573f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
5574f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
5575f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5576f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
5577f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
5578f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
5579f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
5580f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
5581f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
5582f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5583f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
5584c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        EvenMoreAsserts.assertImageRawData(
5585c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
5586f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5587f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5588f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
55894e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
55904e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId1 = createRawContactWithName();
55914e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
55924e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId2 = createRawContactWithName();
55934e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
559447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
559547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
55964e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55974e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
55984e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
55994e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
56004e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56014e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
56024e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
56034e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56044e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
56054e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56064e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
56074e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
56084e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
56094e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56104e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
56114e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
56124e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56134e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
56144e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
56154e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
56164e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56174e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
56184e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
56194e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56204e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
56214e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
56224e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
56234e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
56244e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
56256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
56266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId1 = createRawContact(new Account("a", "a"));
56276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
56286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
56296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId2 = createRawContact(new Account("b", "b"));
56316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
56326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
56336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
56356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
56366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
56416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
56426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
56446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
56476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
56486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
56526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
56536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
56566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
56576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
56656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
56666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
56696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
56706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
56736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
56746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
56826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
56856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
56866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
56946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
56976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
56986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
57016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
57026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
57036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
57046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
57066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
57076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
57086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
57096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
57106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
57116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
57136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
57146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
57156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
57166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
57176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
57186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
57196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
57206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
57236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
57246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
57256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
57266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
57276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId = createRawContact(new Account("a", "a"));
57286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
57296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
57316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
57326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
57336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
57346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
57356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
57376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
57386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
57406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
57416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
57426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
57436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
57456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
57466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
57476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
57486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
57506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
57516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
57526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
57536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
57546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
57556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
57566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
57586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
57596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
57606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
57616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
57626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
57636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
57666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
57676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
57706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
57716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
57746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
57756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
57786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
57796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
5781ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
5782ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
5783ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
5784ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5785ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContact();
5786ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("James", "Sullivan");
5787ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("The Abominable", "Snowman");
5788ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mike", "Wazowski");
5789ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("randall", "boggs");
5790ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Boo", null);
5791ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mary", null);
5792ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Roz", null);
5793ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5794ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
5795ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
5796ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_PRIMARY + " COLLATE LOCALIZED");
5797ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
579835997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "", "B", "J", "M", "R", "T");
5799ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
5800ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
5801ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5802ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
5803ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
5804ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
5805ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
580635997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", "");
5807ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
5808ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
5809ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5810ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5811ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
5812ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
5813ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
5814ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
5815ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5816ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5817ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
5818ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
5819ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
5820ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
5821ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5822ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5823f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
5824f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
5825f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
5826f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
5827f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
5828f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
5829f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
5830f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
5831f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
5832f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
5833f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
5834f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
5835f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5836f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5837f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
5838f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
5839f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
5840f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
5841f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5842f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5843f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
5844f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
5845f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
5846f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
5847f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
5848f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
5849f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
5850f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
5851f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
58525fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
58535fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
58545fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
58555fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
58565fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
58575fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
58585fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
58595fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
58605fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
58615fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
58625fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
58635fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
58645fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
5865f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5866f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5867e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
5868e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
5869e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
5870e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
5871e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5872e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
5873e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
5874e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5875e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5876e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5877e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5878e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5879e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
5880e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
5881e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
5882e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
5883e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5884e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
5885e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
5886e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
5887e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5888e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri insertUri = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, blue);
5889e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5890e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
5891e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
5892e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5893e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5894e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5895e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5896e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
58973826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
58983826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
58993826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
59003826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
59013826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
59023826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        long rawContactId = createRawContact();
59033826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
59043826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
59053826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
59063826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
59073826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
59083826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
59093826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
59103826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
5911bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{ACCOUNT_1});
59123826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{ACCOUNT_1});
59133826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
5914bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
59153826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
59163826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
59173826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
59183826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
59193826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
592009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
592109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
592209c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
592309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
59243826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
592509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
592609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
592709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
5928b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
5929743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
5930b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
5931b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
5932b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
5933b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
5934b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
5935b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
5936b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
5937b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
5938b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
5939b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
5940b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
5941b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
594242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
594342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
594442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
594542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
594642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
594742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
594842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
594942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
595042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
595142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
595242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
595342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
595442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
595542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
595642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
595742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
595842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
595942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
596042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
596142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
596242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
596342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
596442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
596542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
596642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
596742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId1 = createRawContact(mAccount, RawContacts.SOURCE_ID, "4:12");
596842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId1, "John", "Doe");
596942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
597042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId2 = createRawContact(mAccount, RawContacts.SOURCE_ID, "3:4%121");
597142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId2, "Jane", "Doh");
597242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
597342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
597442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
597542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
597642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
597742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
597842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
597942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
598042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
598142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
598242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
598342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
598442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
598542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
598642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
598742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
598842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
598942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
599042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
599142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
599242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
599342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
599442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
599542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
599642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
599742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
599842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
599942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
600042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
600142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
600242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
600342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
600442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
600542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
600642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
600742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
600842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
600942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
601042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
601142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
601242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
601342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
601442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
601542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
601642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
601742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
601842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
601942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
602042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
602142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
602242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
602342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
602424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
602524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
602624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
602724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
602824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
602924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
603024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
603124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
603224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
603324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
603442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
603542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
603642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
603742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
603842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
603942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
604042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
604142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
604242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
604342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
604442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
604542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
604642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
604742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
604842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
604942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
605042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
605142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
605242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
605342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
605442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
605542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
605642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
605742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
605842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
605942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
606042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
606124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
606224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
606324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
606442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
606542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
606642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
606742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
606842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
606942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
607042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
607142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
607242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
607342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
607442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
607542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
607642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
607742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
607842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6079dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
6080dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6081dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6082dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
6083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
6084dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6085dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccountTwo);
6086dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(null);
6087dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6088dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6090dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6091dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6098dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6099dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6100dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6101dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
6102dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
6103dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6104dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6105dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6106dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6107dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6108dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6109dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
6110dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6111dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6112dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount);
6113dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo);
6114dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
6115dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null);
6116dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6117dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6118dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6119dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6120dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6121dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6122dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
6123dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6124dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6125dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6126dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6127dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6128dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
6129dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
6130dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
6131dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
6132dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
6133dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
6134dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
6135dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6136dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount, RawContacts.STARRED, "1");
6137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo, RawContacts.STARRED, "1");
6138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
6139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null, RawContacts.STARRED, "1");
6140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r7 = createRawContact(null);
6141dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6142dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6144dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6145dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6146dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6147dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
6148dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6149dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6150dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6151dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6152dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6153dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6154dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6155dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6156dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6157dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6158dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6159dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6160dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6161dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6162dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6163dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6164dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6165dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6166dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6167dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6168dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6169dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6170dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6171dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
6172dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
6173dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
6174dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6175dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6176dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6177dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6178dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6179dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6180dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6181dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6182dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6183dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6184dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6185dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
6186dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6187dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6188dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6189dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6190dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6191dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
6192dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6193dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6194dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6195dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6196dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6197dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6198dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6199dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6200dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6201dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6202dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6203dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6204dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6205dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
6206dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6207dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
6208dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
6209dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
6210dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
6211dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6212dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
6213dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6214dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6215dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6216dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6217dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6218dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6219dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6220dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6221dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6222dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6223dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6224dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6225dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6226dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
6227dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6228dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6229dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6230dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6231dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6232dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
6233dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
6234dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
6235dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
6236dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
6237dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6238dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6239dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6240dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6241dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6242dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6243dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6244dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6245dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6246dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6247dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6248dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6249dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
6250dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6251dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6252dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6253dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6254e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
6255dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
6256dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6257dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
6258dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
6259dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
6260dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
6261dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
6262dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6263dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6264dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6265dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6266dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6267dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6268dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6269dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6270dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6271dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6272dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6273dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6274dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
6275dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6276dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6277dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6278dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6279dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6280dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
6281dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6282dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
6283dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
6284dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
6285dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6286dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6287dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
6288dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6289dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6290dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6291dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6292dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6293dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
6294dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6295dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
6296dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
6297dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
6298dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
6299dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6300dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6301dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6302dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6303dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6304dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6305dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6306dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6307dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6308dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6309dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6310dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6311dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6312dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6313dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
6314dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
6315dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
6316dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6317dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6318dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6319dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
6320dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6321dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6322dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6323dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
6324dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
6325dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
6326dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6327dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6328dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6329dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6330dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6331dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6332dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6333dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
6334dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6335dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6336dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6337dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6338dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6339dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6340dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
6341dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
6342dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
6343dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6344dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6345dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6346dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6347dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6348dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6349dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
635097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
635197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
635297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
635397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
635497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
635597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
635697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
635797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
635897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
635997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
636097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
636197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
636297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
636397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
636497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
636597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
636697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
636797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
636897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
636997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
637097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
637197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
637297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
637397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
637497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
637597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
637697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
637797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
637897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
637997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
638097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
638197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
638297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
638397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
638497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
638597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId1 = createRawContact();
638697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
638797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
638897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
638997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId2 = createRawContact();
639097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
639197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
639297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
639397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
639497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
639597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
639697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
639797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
639897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
639997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
640097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
640197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
640297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
640397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
640497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
640597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
64067a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
64077a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
64087a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
64097a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
64107a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
64117a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
641217a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
64137a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
64147a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
64157a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
64167a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
64177a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
64187a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
64197a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
64207a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
64217a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
64227a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
64237a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
64247a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
64257a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
64267a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
64277a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
64287a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
64297a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
64307a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
64317a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
64327a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
643355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
64347a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
64357a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
64367a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
64377a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
64387a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
64397a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
64407a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
64417a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
64427a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
64437a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
64447a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
6445084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    public void testBuildSingleRowResult() {
6446084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
6447084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b"},
6448084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
6449084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
6450084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2}
6451084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
6452084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6453084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
6454084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b", "a", "b"},
6455084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
6456084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
6457084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2, 1, 2}
6458084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
6459084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6460084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
6461084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                null, // all columns
6462084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
6463084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
6464084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2}
6465084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
6466084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6467084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
6468084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            // Access non-existent column
6469084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            ContactsProvider2.buildSingleRowResult(new String[] {"a"}, new String[] {"b"},
6470084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                    new Object[] {1});
6471084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            fail();
6472084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } catch (IllegalArgumentException expected) {
6473084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
6474084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
6475084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6476084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    private void checkBuildSingleRowResult(String[] projection, String[] availableColumns,
6477084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            Object[] data, Integer[] expectedValues) {
6478084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        final Cursor c = ContactsProvider2.buildSingleRowResult(projection, availableColumns, data);
6479084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
6480084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertTrue(c.moveToFirst());
6481084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(1, c.getCount());
6482084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(expectedValues.length, c.getColumnCount());
6483084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6484084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            for (int i = 0; i < expectedValues.length; i++) {
6485084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                assertEquals("column " + i, expectedValues[i], (Integer) c.getInt(i));
6486084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            }
6487084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } finally {
6488084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            c.close();
6489084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
6490084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
6491084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
6492dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
6493dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = mResolver.query(maybeAddAccountQueryParameters(Data.CONTENT_URI, account),
6494dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
6495dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
6496dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
6497dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
6498dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6499dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
650042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
650142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
6502bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
650342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
650442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
6505bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
6506bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
6507bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
6508bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
6509bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
6510bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
6511bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
651242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
6513bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
6514bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
651542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
651642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
651742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
651842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
651942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
652042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6521f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
6522f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
6523f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
6524f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6525f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
65264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
65274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
6528aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
652924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
653024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
653124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
653224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
653324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
653424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
653524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
653648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
653724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
653848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
653948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
654048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
654148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
6542aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
654348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
6544aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
654548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        insertStructuredName(rawContactId, firstName, givenName);
654648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
654748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
654848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
654924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
655024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
655124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
655224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
655324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
655424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        insertStructuredName(rawContactId, firstName, givenName);
655524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
655624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
655724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
655848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
6559aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
656024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
656124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
656224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
656324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
656424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
656524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
656624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
65674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
65684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
65694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
65704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
657124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
657224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
657324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
657424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
657524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
65764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
65774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
65784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
65794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
65809dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
65819dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
65829dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
65839dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
65849dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
65859dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
65864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
6587aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
65885d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
65894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
65904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
65914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
65924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
659324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
659448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
65954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
65964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
659724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
659824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
659924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
660024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
660124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
660224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
660324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
660424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
660524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
660624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
660724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
660824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
660924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
661024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
661124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
661224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
661324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
661424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
661524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
661624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
661724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
661824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
661924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
662024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
662124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
662224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
662324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
662424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
66254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
66264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
66274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
66284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
66294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
66304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
66314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
66324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
66334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
66344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
66354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
66364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
66374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
66384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
66394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
66404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
66414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
66424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
66434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
66444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
66454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
66464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
66474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
66484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
66494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
66504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
66514928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
66524928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
66534928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
66544928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
66554928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
66564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
66574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
66584928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
66594928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
66604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
66614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
66624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendPath(String.valueOf(dataId))
66634928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
66644928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .build();
66654928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertNotSame(0, mResolver.update(feedbackUri, new ContentValues(), null, null));
66664928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
66674928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
66684928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
66694928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
6670d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
6671