ContactsProvider2Test.java revision 5f673b204620c4c241b3b39c6ac0ee063d22f13b
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
9264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
927e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
928e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
929e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
930e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
931e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
932e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
933e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
934e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
935e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
936e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
937e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
938e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
939e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
940e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
941e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
942e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
943e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
944e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
945e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
9465e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
9475e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
948e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final long rawContactId2 = createRawContactWithName("Chilled", "Guacamole", ACCOUNT_2);
9492a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
95058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
95158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
9525e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
953e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
9544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
9554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
9564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
9575e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
9584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
9594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
9605e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
9614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
962e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
9635e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
9645e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
965e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
9665e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
9675e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
968e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
9695e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
97045d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
971e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
97245d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
97358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
97458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
97558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
97658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
97758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
97858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
97958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
98058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
98158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
98258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
98358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
98458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
98558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
98658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
98758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
98858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
98958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
99058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
99158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
99258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
99358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
99458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
995e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
996e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
997e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
998e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
999e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1000e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1001e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1002e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1003e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1004e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1005e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1006e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1007e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1008e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1009e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1010e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1011e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1012e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1013e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1014e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1015e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1016e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1017e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1018e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1019e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1020e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1021e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1022e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1023e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1024e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1025e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1026e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1027e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1028e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri3, values);
1029e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1030e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
103158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
10324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1034e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1035e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1036e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1037e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1038e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1039e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1040e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1041e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1042e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
10434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
10444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1045ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1046ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1047ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
10484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1049e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1050e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1051e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1052e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1053e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1054e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1055e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1056e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1057e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1058ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
10594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1060892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
106134984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1062e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
106334984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
1064892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1065892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1066892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1067892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1068892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1069892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1070892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1071892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1072892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1073892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1074892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1075892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1076892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1077892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1078892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1079892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1080892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1081892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1082892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1083892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1084892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1085892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1086892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1087892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1088892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1089892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1090892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1091892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1092892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1093892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1094892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1095892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1096892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1097892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1098892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1099892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot1", "Tamale");
1100892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1101892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1102892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1103892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1104892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1105892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1106892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1107892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1108892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1109892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1110892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1111892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1112892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1113892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1114892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1115892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1116892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1117892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1118892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1119892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot2", "Tamale");
1120892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1121892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1122892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1123892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1124892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1125892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1126892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1127892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1128892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1129892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1130892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
11314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
11324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
113356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
113456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Checks the logic that relies on using the trailing 7-digits as a fallback for phone
113556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // number lookups.
113656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
113756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
113856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
113956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
114056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
114156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
114256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertStructuredName(rawContactId, "Senor", "Chang");
114356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
114456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
114556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
114656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
114756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
114856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
114956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
115056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
115156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
115256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
115356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with +0 prefix should also match.
115456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
115556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+097427289"), null, null));
115656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
115756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
115856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
115956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
116056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
116156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
116256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
116356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
116456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
116556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
116656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
116756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
116856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
116956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
117056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
117156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
117256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
117356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
117456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
117556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
117656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
117756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
117856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertStructuredName(rawContactId, "Senor", "Chang");
117956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
118056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
118156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
118256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
118356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
118456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
118556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
118656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
118756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
118856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
118956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
119056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
119156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
119256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
119356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
119456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
119556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
119656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1197653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1198653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1199653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1200653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1201653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1202653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        insertStructuredName(rawContactId, "Hot", "Tamale");
1203653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1204653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1205653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1206ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
1207ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
1208ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
1209653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1210653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1211653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1212653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1213653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1214ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1215ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
1216653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1217653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1218653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1219653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1220653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1221653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1222ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1223653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1224653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1225653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1226653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1227653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1228653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1229ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1230ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
123181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1232653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1233653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1234e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
1235e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
1236e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long rawContactId1 = createRawContactWithName("Meghan", "Knox");
1237e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
1238e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
1239e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1240e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long rawContactId2 = createRawContactWithName("John", "Doe");
1241e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
1242e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
1243e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
1244e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1245e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1246e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
1247e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
1248e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
1249e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1250e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
1251e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
1252e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
1253e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
1254e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1255e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
1256e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
1257e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
1258e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
1259e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1260e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
1261e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
1262e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1263e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
1264e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
1265e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1266e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1267e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
1268e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
1269e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1270e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
12714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
12724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
12734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
12744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
12754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
12764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
12774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
12784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
12808ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
12814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertStructuredName(rawContactId, "Meghan", "Knox");
12838ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
12848ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
12854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12868ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
12874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
12884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
12894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
12904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
12914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
12924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
12934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
12944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
12954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
12964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
12974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
12984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
12994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
13004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
13014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13028ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
130348828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
13044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
13058ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13068ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
13078ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
13088ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
13098ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
13108ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
13118ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13128ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
13138ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
13148ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
13158ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13168ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
13178ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
13188ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
13198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
13208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
13218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
13238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
13248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
13258ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
13268ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
13278ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13305e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
13314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Hot", "Tamale");
13324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
13334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13345e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
13354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
13364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
13374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
13384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
13394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
13404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
13414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
13424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
134308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
134408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
134508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
134608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
134708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
13484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13505e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
135147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("Hot", "Tamale", ACCOUNT_1);
13525e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
13535e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
13545e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
135547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("Hot", "Tamale", ACCOUNT_2);
13565e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
13575e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
13585e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
13595e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
13605e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
13615e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
13625e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
13635e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
13645e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
13655e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
13665e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
13675e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
13685e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
13695e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1370155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
13715e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
13725e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
13731e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
13745e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
13755e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
13765e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
13775e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
13785e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
13795e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
13807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1381c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1382c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1383c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
1384c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1385c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1386c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1387c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1388c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1389c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1390c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1391c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1392c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1393c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1394c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1395c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1396c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v1, v2, v3 });
1397c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1398c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1399c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1400c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1401c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1402c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
1403c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        long rawContactId1 = createRawContact();
1404c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1405c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1406c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1407c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1408c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1409c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1410c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1411c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1412c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1413c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1414c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1415c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
14167d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
14177d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
14187d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
14197d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
14207d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId1 = createRawContact(ACCOUNT_1);
14217d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
14227d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        long rawContactId2 = createRawContact(ACCOUNT_2);
14237d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
14247d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
14257d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
14267d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
14277d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
14287d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14297d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14307d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
14317d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_1.type)
14327d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14337d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
14347d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14357d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14367d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
14377d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, ACCOUNT_2.type)
14387d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14397d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
14407d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14417d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
14427d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14437d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_1.name)
14447d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14457d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2 });
14467d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
14477d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
14487d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, ACCOUNT_2.name)
14497d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
14507d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
14517d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
14527d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
145346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
145446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
145546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId1 = createRawContact();
14564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
14574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
145846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        long rawContactId2 = createRawContact();
14594928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
14604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
14614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
14624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
146346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
146446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
146546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
146646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
146746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
146846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
146946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
147046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
147146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
147246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
147346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
147446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
147546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
147646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
147746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
147846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
147946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
148046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
148146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
148246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
148346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
148446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
148546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
148646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
148746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
148846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
14894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
149046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
149146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // account3@email.com should be the first. account2@email.com should also be promoted as
149246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        // it has same contact id.
149346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
149446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
149546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
149646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1497f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1498f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1499f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1500f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1501f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
1502f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long rawContactId1 = createRawContact();
1503f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1504f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1505f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1506f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1507f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1508f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1509f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1510f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1511f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1512f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1513f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1514f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1515f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1516f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1517f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1518f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1519f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1520f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1521f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1522f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1523f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1524f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1525f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1526f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1527f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1528f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1529f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1530f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1531f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1532f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1533f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1534f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1535f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1536f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1537f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1538f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1539f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1540f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1541f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1542f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1543f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1544f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1545f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1546f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1547f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1548f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1549f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1550f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1551f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1552f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1553f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1554f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1555f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1556f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1557f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1558f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1559f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1560f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1561f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
15624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
15634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = createRawContactWithName("Alice", "Nextore");
15644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
15658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
15664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
15684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
15694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
15704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
15714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
15724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
15734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
15744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
15754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
15768ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
157748828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
157848828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
15794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
15808ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
15818ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
15828ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
15838ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
15848ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
15858ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
15868ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
15878ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
15888ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
15898ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
15908ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
15918ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
15928ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
15938ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
15948ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
15958ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
15968ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
15978ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
15988ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
15998ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
16008ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16018ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
16028ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
16038ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
16048ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
16054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
16084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1610aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1611d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
16124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
16134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
16154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
16164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
16194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
1621aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1622aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
162382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1624aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
1625ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
1626ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
1627ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
16284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1630a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
163248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1633aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1634d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1635aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
163648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
163748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
163848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
163948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
16403b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
16413b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
16427ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, nameValues);
164348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
164448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
164582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
164648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1647ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
1648ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
16494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
165048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
16513b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
165248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
1653a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
16543b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
16553b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
1656a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
16577ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
16587ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
16597ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
16607ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
16617ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
16627ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
16637ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
16647ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
16657ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
1666a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1667a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1668a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1669a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
1670a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1671a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1672a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1673a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1674a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1675a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1676a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1677a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1678a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1679a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1680a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1681a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
1682a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1683a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1684a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
1685a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
1686a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
1687a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
1688a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
1689a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1690a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
1691a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
1692a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
1693a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
1694a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1695a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
1696a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
1697a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
1698a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
1699a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
1700a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
1701a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1702a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        insertStructuredName(rawContactId, "James", "Bond");
1703a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1704a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
1705a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
1706a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1707a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
1708a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
1709a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1710a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
1711a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
1712a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
1713a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
1714a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
1715a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
1716a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
1717a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
17184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
17194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
17202f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
17212f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
17222f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
17232f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
1724ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
17254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
17262f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
17272f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
17284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
17292f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
1730d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
17314928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
17324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
17334928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
1734aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
1735aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
17364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
17372f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
17382f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
17392f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
17402f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
1741d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
17424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
17439dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
1744aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
1745d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
17464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
17472f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
17482f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
17492f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
17502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17512f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
17524928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
17532f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17542f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
17552f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
17562f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
17572f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17584928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
17592f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
17604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
17612f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17622f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
17632f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
17644928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
17652f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
17669dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
17679dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
17689dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
17692f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
17702f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
17712f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
17729dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
17739dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
17749dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Now the 4th contact has a phone number.
17759dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        insertPhoneNumber(rawContactId4, "18004664414");
17769dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
17779dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Phone only strequent should return 4th contact.
17784928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
17794928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
17804928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
17814928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
17824928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
17834928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
17844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
17854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1786ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
17872f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
17884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
17894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
179045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
179145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
179245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
179345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
179445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
179545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
179645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
179745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
179845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
179945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
180045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
180145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
180245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
180345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
180445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
1805363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
1806363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
180745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
180845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
180945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
181045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
181145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
181245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
181345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
181445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
181545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
181645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
181745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
181845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
181945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
182045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
182145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
182245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
182345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
182445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
182545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
182645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
182745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
1828363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
1829363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
1830363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1831363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
1832363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
1833363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1834363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
1835363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
1836363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
1837363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
1838363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
1839363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
1840363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
1841363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
1842363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1843363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
1844363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
1845363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
1846363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
1847363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
184845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
184945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
1850ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
18514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
18524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
18534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
18544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
1855aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
1856aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
18574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
18584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
18594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
1860aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
1861aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
18624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1863ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
18644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
18654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
18664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
18674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
18684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
18694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1870ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
18714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
18724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
18734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
18744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
18754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1876ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
18774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
18784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
18794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
18803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
18813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
188236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
188336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
188424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
188524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
188636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
188736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
188824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
188936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
189024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
189124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
189224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
189324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
189424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
189536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
189636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
189736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
189836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
189936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
190036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
190136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
190236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
190336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
190436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
190536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
190624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
190724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
190836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
190936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
191036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
191136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
191224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
191324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
191436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
191536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
191636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
191736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
191824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
191924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
192024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
192124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
192224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
192324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
192424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
192524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
192624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
192736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
192836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
192936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
193036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
193124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
193224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
193324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
193424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
193524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
193624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
193724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
193836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
193936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
194036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
194136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
194224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
194324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
194424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
194524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
194624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
194724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
194824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
194924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
195024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
195136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
195236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
195336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
195424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
195524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
195636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
195736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
195836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
195936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
196036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
196124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
196224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
196336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
196436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
196536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
196636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
196736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
196824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
196924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
197024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
197124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
197224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
197324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
197424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
197524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
197624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
197724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
197824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
197924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
198024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
198136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
198236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
198336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
198436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
198524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
198624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
198724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
198824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
198924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
199024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
199124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
199236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
199336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
199436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
199536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
199624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
199724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
199824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
199924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
200024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
200124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
200224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
200324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
200424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
200524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
200624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
200724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
200824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
200924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
201024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
201124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
201224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
201324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
201424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
201524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
201624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
201724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
201824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
201924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
202024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
202124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
202224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
20236ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
20246ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
20256ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
20266ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20276ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
20286ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long rawContactId = createRawContactWithName("Domo", "Arigato");
20296ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
20306ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
20316ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
20326ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
20336ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20346ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
20356ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
20366ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
20376ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
20386ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
20396ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
20406ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20416ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
20426ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
20436ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
20446ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
20455d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
204624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
204724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
204824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
204924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
205024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
205124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
205224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
205324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
20545d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
205524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
20565d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
20575d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
205824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
205924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
206024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
206124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
206224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
206324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
206424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
206524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
206624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
206724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
206824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
206924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
207024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
207124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
207224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
207324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
207424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
207524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
207624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
207724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
207824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
207924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
208024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
208124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
208224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
208324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
208424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
208524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
208624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
208724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
208824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
208924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
209024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
209124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
209224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
209324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
209424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
209524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
209624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
209724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
209824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
209924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
210024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
210124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
210224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
210324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
210424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
210524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
210624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
210724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
210824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
210924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
211024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
211124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
211224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
211324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
211424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
211524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
211624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
211724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
211824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
211924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
212024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
212124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
212224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
212324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
212424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
212524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
212624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
212724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
212824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
212924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
213124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
213224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
213324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
213424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
213524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
213724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
213824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
213924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
214024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
214124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
214224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
214324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
214424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
214524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
214624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
214724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
214824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
214924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
215024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
215124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
215224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
215324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
215424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
215524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
215624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
215724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
215824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
2159cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
2160cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
2161cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
2162cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
2163cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
2164cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
2165cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
2166cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2167cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
2168cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
2169cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2170a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
2171a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
2172a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
2173a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2174a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
2175a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
2176a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
2177a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Uri profileUri = maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI, account)
2178a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
2179a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
2180a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
2181a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
2182a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2183a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
2184a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
2185a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
2186a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
218785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
218885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
218985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
219085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        assertInputStreamContent(
219185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
219285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
219385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
219485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
219585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
219685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
219785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
219885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        assertInputStreamContent(
219985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
220085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
220185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
220285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
22030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
220419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
220519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
220619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
220719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
220819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
220919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
221019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
221119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
221219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
221319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
221419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
221519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
221682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
2217aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
2218aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
221982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
2220aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
2221aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
222219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
222319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
222482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
222519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
2226a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
2227a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
222819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
222919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
223019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
223119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
223219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
223382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
22340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
223519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
223619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
223719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2238a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
223919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
224019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
224119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
224219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
224319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
224482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
22450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
224619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
224719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
224819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2249a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
225019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
225119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
225219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
225319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
225419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
225589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
225689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
225789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
225889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
225989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
226089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
226189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
226289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
226389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
226489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
226589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
226689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
226789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
22683cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
22693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
22703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
22713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
22723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
22739d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
22743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
22753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
22763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
22773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
22783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
22793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
22803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
22813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
228294021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
22833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
22843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
22853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
22863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
22873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
22883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
22893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
229073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
22913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
22923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
22933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
2294f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
2295f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2296f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2297f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2298f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
2299f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2300f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
2301f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2302f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2303f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
2304f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2305f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2306f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
2307f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2308f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
2309f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
2310f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
2311f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2312f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2313f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
2314f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long rawContactId1 = createRawContact(mAccount);
2315f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
2316f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2317f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
2318f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
2319f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
2320f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
2321f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
2322f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
2323f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
2324f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
2325f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
2326f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
2327f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
2328f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2329f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
23305f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
23315f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
23325f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
23335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23345f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
23355f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
23365f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
23375f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23385f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
23395f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
23405f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
23415f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
23425f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23435f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
23445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
23455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
23465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
23485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
23495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
23505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
23525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
23535f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
23545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
23565f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
23575f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23585f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
23595f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
23605f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
23615f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23625f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
23635f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
23645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
23655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23665f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
23675f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
23685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
23695f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
23705f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
23715f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
23725f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
23735f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23745f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
23755f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
23765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
23775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
23795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
23805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
23815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
23835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
23845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
23855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
23865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
23875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
23885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
2389f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
2390f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
2391f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
2392f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
2393f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
2394f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
2395f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2396f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
2397f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
2398f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId0 = createRawContactWithName("firstName0", "lastName0");
2399f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2400f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId1 = createRawContactWithName("firstName1", "lastName1");
2401f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
2402f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
2403f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2404f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId2 = createRawContactWithName("firstName2", "lastName2");
2405f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
2406f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
2407f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
2408f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2409f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2410f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
2411f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
2412f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
2413f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
2414f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
2415f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
2416f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
2417f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2418f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2419f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
2420f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
2421f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
2422f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
2423f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
2424f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
2425f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
2426f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2427f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
2428f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
2429f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
2430f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
2431f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
2432f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
2433f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
2434f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
2435f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2436f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2437f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2438f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
2439f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
2440f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
2441f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
2442f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2443f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2444f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2445f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
2446f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long rawContactId3 = createRawContactWithName("firstName3", "lastName3");
2447f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
2448f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
2449f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
2450f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
2451f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
2452f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2453f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
2454f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
245518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
245618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
245718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
245818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
245918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
246018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
246118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
246218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
246318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
246418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
246518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
246618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2467f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
2468f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
2469f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
2470f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
2471f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
247218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
247318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
247418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
247518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
247618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
247718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2478f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
2479f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
2480f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
2481f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
2482f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
2483f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
2484f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
2485f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
248618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
248718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
248818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
248918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
249018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
249118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
2492f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
249323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
249423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
249523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
249623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
249723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
249823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
249923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
250023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
250123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
250223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
250323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
250423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
2505f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
2506f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
250789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
250889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
250989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
2510f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
251189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
251289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
2513f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
251489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
251589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
2516f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
2517f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
2518f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
2519f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
2520f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
252189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
252289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
2523f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
252489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
2525f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
252689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
2527f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
2528f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
2529f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
2530f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
2531f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
2532f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
2533f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
2534f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
2535f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
2536f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
2537f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
25380e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
25390e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
25400e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
25410e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
25420e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
25430e21a867a572679d64d79041eb574d13665178d4Dave Santoro
25440e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
25450e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
25460e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
25470e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
25480e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
254989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
255089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
25514097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
2552d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
25534097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
25544097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
25555ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
25564097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
255717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
25584097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
25594097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
256067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
256167c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        long rawContactId = createRawContact();
256267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
256367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
256467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
256567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
256667c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        insertStructuredName(rawContactId, values);
256717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
256867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
256967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
25704097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
2571d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
25724097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
25734097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
25744097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
25755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        insertStructuredName(rawContactId, values);
25764097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
25775ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
25784097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
25794097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
25805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
25815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        final long rawContactId = createRawContact(null);
25825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
25845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
25855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
25865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
25875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
25885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
25895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
25905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
25915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
25925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
259355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
259455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
25955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
25965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
25975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
25985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
25995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
26015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
26025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
260555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
260655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
26075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
26085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
26105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
26115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
26135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
26145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
26155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
26175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
26185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
26215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // Only run this test when Chinese collation is supported
26235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
26245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
26255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
26265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
26285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
26305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
26315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
26325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
26355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
26365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
26375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
26385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26394cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26404cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
26435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
26445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
26475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
26485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
26495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
26505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
26514cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26524cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B");
26535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
26555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
26565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
26575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
26595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
26605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
26635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact(null);
26645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
26665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
26675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
26685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri dataUri = insertStructuredName(rawContactId, values);
26695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
26725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
26735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
26745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
26755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
26765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
26775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
26785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
26805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
26815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
26835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
26845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
26855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
26865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
26875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
26885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
26895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
26905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
26925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
26935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
26945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
26955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
26965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
26975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
26985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
269925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
270025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId1 = createRawContact();
270125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
270225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
270325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        long rawContactId2 = createRawContact();
270425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
270525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
27060c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
27070c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
270825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
270925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
271025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
271125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertStructuredName(rawContactId2, "Potato", "Head");
271225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
271325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
271481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
271525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
271625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
271701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
271801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long rawContactId = createRawContact();
271901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2720a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
272101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
272201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
272301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
272401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
272501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
272601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
272701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
272801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
272901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
273001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
273101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
273201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
273301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2734a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
2735a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2736a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
27375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
273801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
273901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
2740a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
2741a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
2742a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
2743a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
2744a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
2745a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
2746a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
2747a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
2748a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
2749a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertStructuredName(rawContactId, values);
27505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
27515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
27525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
27545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
27555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
27565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
27575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
27595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
27615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
27635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
27645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
27655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
27675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
27695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
27705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
27735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
27745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
27755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
27765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
27775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
27785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
27795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
27815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
27825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
27835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
27845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
27865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
27885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
27905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
27915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
27925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
27935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
27945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
27955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
27965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
27975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
27985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
27995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
28005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
28015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
28030b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        boolean hasChineseCollator = false;
28040b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        final Locale locale[] = Collator.getAvailableLocales();
28050b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        for (int i = 0; i < locale.length; i++) {
28060b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            if (locale[i].equals(Locale.CHINA)) {
28070b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                hasChineseCollator = true;
28080b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov                break;
28090b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            }
28100b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
28110b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
28120b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        if (!hasChineseCollator) {
28130b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
28140b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
28150b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
28165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long rawContactId = createRawContact();
28175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
28185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
28195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
28215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
28235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
28255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
28265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
28275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
28285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
28295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
28305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
28314cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_PRIMARY, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
28324cd13c4266d8e476e1a49c4b6bcd5b18c33d0de3Bai Tao        values.put(Contacts.SORT_KEY_ALTERNATIVE, "ZHONG \u4E2D GUO \u56FD DIAN \u7535 XIN \u4FE1");
28335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
283401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
283501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
283631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
283731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long rawContactId = createRawContact();
283831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
283931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
284031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
284131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
284231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
284331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
284431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
284531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
284631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
284731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
284831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
284931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
285031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
285131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
285231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
285331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
285431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
285531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
285631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
285731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
285831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
285931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
286031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
286131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
286231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
286331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
286431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
286531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
286631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
286731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
286831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
286931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
287031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
287131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
287231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
287331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
287431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
287531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
287631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
287731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
287831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
287931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
288031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
288131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
288231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
288331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
2884a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
2885a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, filter);
2886a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
2887a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2888a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2889916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
2890916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2891916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2892916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2893916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
2894916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
2895916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2896916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2897916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2898916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
28999c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
2900916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
2901916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2902916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
2903916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
2904916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2905916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2906916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
2907916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
2908916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
2909916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2910916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
2911916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2912916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29136f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
2914916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2915916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2916916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
29173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "engineer, [acmecorp]");
2918916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2919916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2920916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2921916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
2922916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContact();
2923916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2924916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2925916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "John", "Doe");
2927916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
2928916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29296f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
2930916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2931916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2932916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
29333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[acme@corp.com]");
2934916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
2935916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
2936916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2937fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
2938fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
2939fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
2940fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
2941fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
2942fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
2943fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
2944fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
2945fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
2946fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
2947fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
2948fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
2949fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
29503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
29513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
29523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
29533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
29543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
29553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
29563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
29573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
29583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
29593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
29603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
29613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
29623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
29643716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
29663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
29683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
29703716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
29723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
29743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
29753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
29763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
29773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
29786f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
29796f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
29806f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
29816f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
29826f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
29836f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
29846f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
29856f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
29866f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
2987916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
2988916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long rawContactId = createRawContactWithName();
2989916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2990916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
2991916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2992916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
2993916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
29946f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
2995916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
2996916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
2997916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
299830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        values.put(SearchSnippetColumns.SNIPPET, "[Incredible]");
2999916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3000916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3001916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
30023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
30033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertStructuredName(rawContactId, "Cave", "Johnson");
30063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
30073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30136f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
30146f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("john", true), emptySnippet);
30153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
30183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
30213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
30223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30286f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
30293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
30323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
30353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
30363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
30373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
30383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
30393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
30403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30466f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("aperture", true), emptySnippet);
30473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
30503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
30533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
30543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30606f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("860", true), emptySnippet);
30613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
30643716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long rawContactId = createRawContact();
30653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
30663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
30673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
30683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
30703716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
30713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
30723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
30733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
30746f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
30753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
30763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
3077dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
3078dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long rawContactId = createRawContact();
3079dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri nameUri = insertStructuredName(rawContactId, "Slinky", "Dog");
3080dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3081dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3082dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3083dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3084dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
3085dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3086dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
3087dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
3088dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3089dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3090dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
3091dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3092dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
3093dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3094dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3095dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
3096dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3097dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
3098dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3099dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3100dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
3101dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
3102dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3103d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
3104d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
3105d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
3106d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3107d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
3108d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
3109d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
3110d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
3111d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
3112d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3113d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
3114d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
3115d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
3116d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3117d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
3118d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
3119d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
3120d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
3121c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
3122d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3123d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3124d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3125d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3126d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3127d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
3128d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3129d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3130d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3131d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
3132c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikov        long rawContactId = createRawContactWithName();
3133d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3134d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3135d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
3136d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
313781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
31388c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
31398c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
31408c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
31418c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
3142d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3143d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3144d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
31453cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("a", "b");
3146d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3147d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3148d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
31493cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("c", "d");
3150d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3151d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
3152d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3153d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
31540c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
31550c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3156d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3157d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
3158d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
3159d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3160d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3161d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
31623cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("e", "f");
3163d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3164d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
3165d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
31663cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("g", "h");
3167d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3168d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
3169d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3170d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
31710c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
31720c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3173d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3174d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
31750c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
3176d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3177d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3178d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
31793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("i", "j");
3180d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3181d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3182d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
31833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("k", "l");
3184d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3185d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
3186d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3187d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
31880c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
31890c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3190d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3191d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
31920c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
31930c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3194d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
31953cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
3196d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
3197d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3198d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
319982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
32004dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        long rawContactId = createRawContact();
32010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
32020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
32030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
32050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
32070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
32080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
32090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
32100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
32110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
32120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
32130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
32140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
32150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
32170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
32190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
32210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
32220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
32250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
32260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
32270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
32280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
32290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
32300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
32320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
32360a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
32370a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
32380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
32390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
32400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
32410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32430a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
32440a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
32450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
32460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
32470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
32480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
32490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
32500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
32510a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
32530a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
32540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
32550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
32560a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32570a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
32580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
32600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
32610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
32620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
32640a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32650a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
32660a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
32670a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
32680a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
32690a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
32710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
32720a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
32730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
32740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long rawContactId = createRawContact();
32754dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
32764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
327782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
32784dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
32794dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
3280aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3281aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
32824dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
32834dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
3284aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
3285d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
32864dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
32874dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
3288aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
3289aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
32904dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
32914dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
3292aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
3293aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
32944dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
329582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
329682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
32970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
329882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
32994dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
330082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
33014dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
330282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
33034dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
330482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
33054dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
33064dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
3307bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3308bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3309bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3310bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3311bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
331282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
33130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3314bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3315bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
3316bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
331782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
3318bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long rawContactId = createRawContact();
3319bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3320bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3321bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3322bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3323bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3324bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
332582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
332682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
3327bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3328bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
3329aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
3330aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
3331aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
3332aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
333382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
3334aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3335aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
333682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
3337bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
333882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
333982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3340bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3341bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
33429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
33439705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
33449705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
33459705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
33469705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
33479705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
33489705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
33499705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
33509705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
33519705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
33529705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
33539705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
33549705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
33559705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
33569705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
33579705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
33589705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
33599705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
33609705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
33619705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
33629705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
33639705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
33649705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
33659705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
33669705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
33679705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
33689705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
33699705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
33709705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
33719705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
33729705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
33739705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
33749705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
33759705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
33769705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
33779705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
33789705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
33799705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
33809705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
33819705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
33829705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
33839705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
33849705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
33859705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
338682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
33879705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
338882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
3389a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3390a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
3391a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3392093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
3393093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long rawContactId = createRawContact();
3394093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3395093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3396093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
3397093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3398093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3399093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
3400093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
3401093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
3402093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
3403093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
3404093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3405093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
3406093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3407093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3408093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3409093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
3410093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
3411093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
3412093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
3413093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
3414093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
3415093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
3416093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3417093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
3418093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
3419093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
342082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
3421a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long rawContactId = createRawContact();
3422a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
3423a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
3424a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3425a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3426a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3427aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
34285d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3429aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
34305d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3431aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
34325d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
3433a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
3434a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
3435a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
343682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
343782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
3438bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
34394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
34404dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
344182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
344282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
34434dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
344482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
344582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
3446a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
344782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
34484dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
34494dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
34504dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
34513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
34523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
34543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact(mAccount);
34553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
34573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
34583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
34593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
34603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
34613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
34623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
34653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
34673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
34693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
34703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
34713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
34723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
34733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
34743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
34773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
34793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
34803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
34823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
34833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
34843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
34853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
34863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
34873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
34883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
34893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
34903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
34913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
34923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
34933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
34943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
34953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
34963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
34973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
34983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
34993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
35003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
35013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
35023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
35053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
35083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
35093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
35123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
35153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
35193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
35213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
35223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
35233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
35253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
35263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
35273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
35303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
35333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
35343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
35373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
35383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
35393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
35413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
35423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
35433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
35453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
35463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
35473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
35503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
35523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
35543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
35553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
35563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
35583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
35596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
35603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
35613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
35623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
35643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
35653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
35663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
35693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
35703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
35723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
35733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
35743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
35753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
35773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
35783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
35793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
35803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
35823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
35833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
35846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
35853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
35873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
35886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
35896802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
35903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
35916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
35923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
35943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
35953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
35963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
35973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
35983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
35993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
36003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
36033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
36043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
36053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
36063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
36083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
36093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
36103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
36113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
36133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
36143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
36153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
36166802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
36193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
36206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
36216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
36223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
36233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
36246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
36253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
36273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
36283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
36293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
36303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
36313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
36323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
36333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
36353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
36363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
36373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
36383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
36393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
36403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
36413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
36443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
36463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
36473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
36493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
36503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
36513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
36533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
36543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
36563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
36573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
36583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
36593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
36603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
36613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
36623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
36633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
36663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
36683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
36693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
36703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
36713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
36723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
36733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
36743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
36763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
36773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
36783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
36793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
36813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
36833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
36843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
36853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
36863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
36873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
36883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
36893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
36903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
36913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
36923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
36933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
36943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
36953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
36963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
36973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
36983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
36993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
37003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
37013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
37023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
37033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
37043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
37073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
37083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
37113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
37143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
37163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
37173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
37183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
37193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
37203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
37213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
37223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
37253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
37263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
37273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
37283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
37293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
37323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
37343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
37363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
37373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
37393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
37403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
37413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
37423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
37433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
37443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
37453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
37463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
37473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
37483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
37493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
37503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
37523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
37543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
37553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
37563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
37573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
37583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
37593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
37603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
37613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
37623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
37633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
37643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
37673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
37686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
37696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
37703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
37713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
37723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
37736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
37746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
37756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
37766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
37776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                assertInputStreamContent(expectedPhotoBytes,
37786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        mResolver.openInputStream(Uri.parse(photoUri)));
37796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
37803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
37813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
37823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
37833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
37863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
37873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
37883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
37893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
37903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
37913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
37923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
37933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
37943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
37953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
37963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
37973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
37983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
37993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
38013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
38063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
38073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
38083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
38093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
38103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
38113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
38143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38156802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
38163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
38213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
38223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
38233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
38256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
38263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
38273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
38283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
38293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
38303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
38313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
38323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
38336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
38343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
38356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
38366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
38376802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
38386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
38396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
38403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
38433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
38453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
38463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
38473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
38483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
38493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
38503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
38526802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
38536802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
38543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
38553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
38563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
38573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
38583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
38596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
38603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
38616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
38626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
38636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
38646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
38656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
38663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
38693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
38713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
38733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
38743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
38753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
38773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
38783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
38793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
38813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
38823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
38833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
38853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
38863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
38873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
38883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
38893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
38913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
38923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
38933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
38943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
38963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
38973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
38983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
38993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
39003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
39013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
39023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
39043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
39053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
39063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
39073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
39103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
39123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
39143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
39153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
39163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
39173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
39183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
39193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
39203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
39213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
39223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
39233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
39253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
39263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
39273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
39283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
39293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
39303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
39313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
39323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
39333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
39363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long rawContactId = createRawContact();
39373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
39383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
39393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
39403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
39413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
39426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
39433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
39443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
39453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
39463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
39473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
39483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
39503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
395282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
395382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        long rawContactId = createRawContact(mAccount);
395482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
395582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
395682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
395782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
395882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
395982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
396082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
396182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
396282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
396382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
396482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
396582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
396682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
396782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
39683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
39693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
39703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
39713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
39723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
39733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
39746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
39756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
39766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
39776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
39786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
39796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
39806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
39816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
39826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
39836802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
39846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
39856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
39866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
39876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
39886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
39894747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
3990d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
3991d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
3992d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
3993d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
3994d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
3995d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
3996d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
3997d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
3998d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
3999d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
4000d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
4001d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
4002d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
4003d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
4004d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4005d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
4006d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
4007d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
4008d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4009d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
4010d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
40114747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
40126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
40136802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
40146802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
40156802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
40166802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
40176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
40196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
40216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
40226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
40236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
40246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
40256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
40266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
40276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
40296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
40306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
40316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
40326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
40336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
40344747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
40356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
40366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
40376802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
40386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
40396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
40406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
404136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
404236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
404336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
404436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
404536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
404636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
404736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
404836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
404936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
405036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
405136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
405236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
405336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
405436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
405536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
405636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
405736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
405836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
405936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
406036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
406136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
406236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
406336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
406436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
406536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
406636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
406736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
406836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
406936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
407036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
407136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
407236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
407336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
407436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
407536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
407636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
407736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
407836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
407936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
408036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
408136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
408236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
408336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
408436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
408536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
408636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
408736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
408836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
408936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
409036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
409136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
409236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
409336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
409436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
409536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
409636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
409736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
409836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
409936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
410036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
410136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
410236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
410336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
410436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
410536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
410636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
410736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
410836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
410936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
411036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
411136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
411236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
411336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
411436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
411536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
411636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
411736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
411836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
411936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
412036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
412136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
412236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
412336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
412436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
412536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
412636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
412736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
412836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
412936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
413036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
413136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
413236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
413336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
413436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
413536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
413636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
413736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
413836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
413936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
414036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
414136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
414236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
414336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
414436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
414536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
414636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
414736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
414836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
414936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
415036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
415136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
415236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
415336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
415436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
415536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
415636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
415736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
415836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
415936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
416036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
416136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
416236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
416336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
416436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
416536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
416636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
416736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
416836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
416936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
417036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
417136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
417236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
417336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
417436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
417536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
417636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
417736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
417836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
417936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
418036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
418136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
418236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
418336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
418436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long rawContactId = createRawContact();
418536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
418636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
418736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
418836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
418936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
419036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
419136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
419236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
419336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
419436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
419536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
419636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
419736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
419836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
419936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
420036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
42013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
42023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
42033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
42043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
42053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
42063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
42073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
42103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
42113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
42126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
42136802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
42143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
42153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
421782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
4218bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
4219bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
4220bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4221d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId1 = createRawContact();
42224dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
4223bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4224aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
4225aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4226aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
4227aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4228aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
4229aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4230bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4231af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
423282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
42334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
4234bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4235bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
423682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
423782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
42380265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
4239bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
4240bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
4241d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
4242d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
4243d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
4244d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
4245d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
4246d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
4247d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
4248d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4249d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4250d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
4251d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
42528c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
42538c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
42548c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
42558c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
42568c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
42578c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
42588c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
42598c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
42608c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
42618c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
42628c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
42638c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
42648c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
4265d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4266d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4267d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
4268d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
4269d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
4270d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
4271d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
4272d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
4273d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
4274d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
4275d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
4276d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
4277d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
4278d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
4279d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
4280d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
42819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
42820be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
42830be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
42840be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
42850be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
42860be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
42870be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
42880be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
42890be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
42900be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
42910be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
42920be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
42930be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
42940be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
42950be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
42960be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
42970be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
42980be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
42990be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
43000be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43010be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
43020be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
43030be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
43040be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43050be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
43060be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
43070be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
43080be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
43090be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
43100db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
43110db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
43120db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
43130db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
43140db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
43150db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
43160db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
43170db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43180db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
43190db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
43200db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
43210db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
43220db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
43230db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
43240db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43250db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
43260db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43270db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
43280db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
43290db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
43300db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
43310db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
43320db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
43330db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
43340db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
43350db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
43360db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
43370db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
43380db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
43390db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
43400db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
43410db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
4342a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
43439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
43449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
43459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
43469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
43479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
43489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
43493cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c0");
43503cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
43513cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
43523cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
43539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
4354226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c1 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c1");
43559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
43569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
43579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
43589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
43599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
4360226c3dc6e93ca76a84c99100caa31045cba06cf6Fred Quintana        long c2 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c2");
43619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
43629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
43639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
43649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
43653cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        long c3 = id = createRawContact(mAccount, RawContacts.SOURCE_ID, "c3");
43669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
43679261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
43689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
43699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
437062318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
437162318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount), null,
437262318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana                RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
43739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
43749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
43759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
43766cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
43779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
43789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
43799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
43809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
43819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
43829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
43839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
43849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
43859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
43869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
43879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
43889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
43899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
43909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
43919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
43929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
43939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
43949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
43956cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
43969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
43979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
43989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
43999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
44009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
44019261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
44029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
44039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
44049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
44059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
44069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
44079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
44089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
44106cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
44119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
44129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
44139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
44149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
44159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
44169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
44179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
44189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
44199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
44209261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
44219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
44229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
44239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
44249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
44253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
44269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
442720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
442820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
4429d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long rawContactId = createRawContact();
443020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
443120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
44325ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
443320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
443420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
443520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
443620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
443720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
443820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
443920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
444020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
444120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
444220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
444320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
444420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
444520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
444620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
444720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
444820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
444920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
445020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
445120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
445220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
445320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
445481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
445520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
445620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
445720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
445820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
445920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
446020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
446120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
446220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
446320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
446420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
446520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
446620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
446720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
446820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
446920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
447020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
447120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
447220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
447320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
447420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
44755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
447620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
447781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
447870b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
447920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
448020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
44815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
448220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
448320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
44845ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
448533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
448681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
448733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
448820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
448989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
449089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
449189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
449289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId1 = createRawContact(account1);
449389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long rawContactId2 = createRawContact(account2);
449489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
449589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri1 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
449689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri uri2 = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
449789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
449889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
449989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
450089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
450189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
450289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
450389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
450489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
450589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
450689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
450789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
4508373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
4509e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId = createRawContact(mAccount);
45105ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
451133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
45124dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
451382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4514aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4515aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4516a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4517a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
451833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
451933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
452082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
45214dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
452233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
452333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
452433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
45255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
452681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
452733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
4528e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
452933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
453033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
453133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
453233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
453382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
45344dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
4535a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
453681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
4537a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
4538a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4539a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
4540e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId1 = createRawContactWithName(mAccount);
4541e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        long rawContactId2 = createRawContactWithName(mAccount);
454247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
454347fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
4544a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4545a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4546a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
4547a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
4548e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
4549a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
4550a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
4551a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
455220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
45531fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
45545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
4555e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        long rawContactId = createRawContact(mAccount);
4556e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
4557e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4558e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
455982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4560aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4561aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4562e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
4563e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
456482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
4565e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
4566e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4567e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
4568e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
4569e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4570e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
4571e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
4572e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
45735f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
45745f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
4575e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
45765870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
4577e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
4578e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
4579e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
4580e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
4581e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
4582e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
4583e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
45845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
45855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
45865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
45875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
45885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
45895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
45905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
45915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        long rawContactId = createRawContact(mAccount);
45925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
45935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
45945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
45955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
45965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
45975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
45985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
45995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
46015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
46025f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
46035f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
46045f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
46055f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
46065f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
4607e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
46085870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
4609e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
4610e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
46119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
46129ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
46139ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
46149ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
46159ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
46169ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
46179ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_1 = Sets.newHashSet(ACCOUNT_1);
46189ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_2 = Sets.newHashSet(ACCOUNT_2);
46199ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(ACCOUNT_1, ACCOUNT_2);
46209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
46229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_1 = Sets.newHashSet(ACCOUNT_1);
46239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_2 = Sets.newHashSet(ACCOUNT_2);
46249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(ACCOUNT_2, ACCOUNT_1);
46259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
46279ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
46289ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
46299ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46309ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
46329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
46339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
46349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
46379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
46389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
46399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
46429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
46439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
46449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
46459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
46479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
46489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
46499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
46509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
46519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
46529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
46549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
46559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
46569ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46579ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
46589ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
46599ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
46609ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
46619ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
46629ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
46639ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
46659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_1 = new Account[] {ACCOUNT_1};
46669ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_2 = new Account[] {ACCOUNT_2};
46679ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_1_2 = new Account[] {ACCOUNT_1, ACCOUNT_2};
46689ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_2_1 = new Account[] {ACCOUNT_2, ACCOUNT_1};
46699ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46709ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
46719ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46729ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
46739ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
46749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
46759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
46779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
46799ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
46809ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
46819ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
46829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
46839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
46849ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
46859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46869ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
46879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
46899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
46909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
46919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
46939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
46959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
46969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
46979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
46989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
46999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
47019ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
47029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
47039ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
47049ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
47059ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
47069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
47079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
4708627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
470970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
471070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
471170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        long rawContactId3 = createRawContactWithName("James", "Sullivan");
471270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
4713627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
4714743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
471570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
471670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4717bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
4718743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
4719743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
4720dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
4721dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
472270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
4723743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId1 = createRawContact(mAccount);
4724743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
4725743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        long rawContactId2 = createRawContact(mAccountTwo);
4726743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
4727743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
4728743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
4729aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
4730aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4731743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
4732bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
4733743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
4734627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
473582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
473670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
473770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
473870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
473933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
474033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
474133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4742bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
474333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
474433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
474533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", readOnlyAccount);
474633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
474733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long rawContactId2 = createRawContactWithName("john", "doe", mAccount);
474833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
474933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
475033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
475133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
475233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
475333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
475433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
475533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
475633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
475733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
475833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
475933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
476033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
476133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
476233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
476333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
476433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4765bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
476633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
476733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
476833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
476933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
477033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
477133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
477233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
477333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
477433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
477533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
477633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
477733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
477833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
477933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
4780c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
4781c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
4782c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
4783c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
4784c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
4785c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
4786c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4787c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
4788c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedRawContactId = createRawContactWithName(doomedAccount);
4789c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
4790c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
4791c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
4792c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
4793c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
4794c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4795c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
4796c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeRawContactId = createRawContactWithName(safeAccount);
4797c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
4798c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
4799c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
4800c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
4801c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
4802c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
4803c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4804c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
4805c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
4806c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
4807c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4808c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
4809c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
4810c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
4811c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
4812c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
4813c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
4814c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4815c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
4816c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
4817c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
4818c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
4819c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
4820c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
4821c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
4822cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
482347fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId1 = createRawContactWithName("John", "Doe", ACCOUNT_1);
482447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        long rawContactId2 = createRawContactWithName("John", "Doe", ACCOUNT_2);
4825cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4826cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
4827cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4828cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
4829cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
4830cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
4831cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4832cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
4833cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
4834cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
4835cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
483673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
483773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        long rawContactId = createRawContact(mAccount);
483873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
483973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
484073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri uri = insertStructuredName(rawContactId, "John", "Doe");
484173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
4842e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
484373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
484473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
484573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
484673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
48475870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
484873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
484981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
48501fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
48511fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
485261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
4853d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
4854d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
485573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
48561fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
48571fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
48581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
48591fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
48601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
486161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
4862c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
486361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
48641fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
48651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
48661fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
48671fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
486881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
48691fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
487061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
487161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
487281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
48731fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
48741fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
487561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
48761fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
487761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
487861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
487961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
48801fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
488181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
48821fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
48831fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
488461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
48851fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
488661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
48871fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
488881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
48891fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
48901fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
489161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
48921fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
489361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
489461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
489561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
489661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
489761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
489861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
48991fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
490061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
49011fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
49021fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
49031fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
49041fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
49051fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
49061fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
49071fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
490861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
490961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        final long rawContactId = createRawContact(mAccount);
49101fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
491161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
49121fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
491361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
491461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
491561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
491661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
49175870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
491861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
491981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
492061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
492161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
49221fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
49234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
49249fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
49259fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
49269fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
49279fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49289fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
49299fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49309fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
49319fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
49329fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
49339fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49349fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
49359fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
49369fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
49379fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49389fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
49399fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
49409fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
49419fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49429fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
49439fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
49449fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
49459fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
49469fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
49479fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
49489fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
49499fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
495060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
495160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
495260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
495360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
495460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
495560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
495660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
495760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
495860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
495960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
496060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
496160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
496260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
496360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
496460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
496560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
496660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
496760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
496860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
496960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
497060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
497160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
497260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
497360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
497460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
497560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
4976074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
4977074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
4978074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
4979074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
4980074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
4981f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
4982f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
4983f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
4984f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
4985f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
4986074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
49873d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
49883d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
4989f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
4990074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
4991074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
4992bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
4993bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long rawContactId = createRawContact();
4994bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
4995bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4996bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
4997bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
4998bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
4999bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
5000bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5001bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
5002bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
5003bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5004bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
5005bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5006bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
5007bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
5008bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
5009bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
5010bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
5011bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5012bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
5013bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertInputStreamContent(thumbnail, mResolver.openInputStream(photoLookupUriWithId));
5014bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertInputStreamContent(thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
5015bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
5016bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5017ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
5018e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov        long rawContactId = createRawContact();
5019f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5020f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5021f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
5022f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
5023f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
5024e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
5025f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.DISPLAY_PHOTO),
5026f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5027f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadTestPhoto(PhotoSize.THUMBNAIL),
5028f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
5029ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
5030ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
5031ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    private static void assertInputStreamContent(byte[] expected, InputStream is)
5032ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            throws IOException {
5033ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        try {
5034ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            byte[] observed = new byte[expected.length];
5035ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            int count = is.read(observed);
5036ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(expected.length, count);
5037ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            assertEquals(-1, is.read());
5038ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            MoreAsserts.assertEquals(expected, observed);
5039ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        } finally {
5040ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert            is.close();
5041ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert        }
5042e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov    }
5043e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
5044732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
5045732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId1 = createRawContact(new Account("a", "a"));
5046f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
5047732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
5048732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5049732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long rawContactId2 = createRawContact(new Account("b", "b"));
5050f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
5051732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
5052732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5053732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5054732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5055732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5056732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5057732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5058f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5059f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5060f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
5061f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
5062f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5063732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5064f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
5065732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5066732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
5067732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5068732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5069732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
5070732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
5071732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
5072732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5073732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5074732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5075732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5076732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5077732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
5078732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5079732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
5080732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5081732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
5082732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
50838e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
50848e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
50858e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
50868e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
50878e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        insertStructuredName(rawContactId, "John", "Doe");
50888e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
50898e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
50908e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
50918e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
50928e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
50938e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
50948e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
50958e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
50968e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
50978e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
50988e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5099155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
51008e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51018e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
51028e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
51038e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
510481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
51058e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
51078e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
51088e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
51098e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
51104e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
51117d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
51127d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
51137d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
51147d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
51157d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51167d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
51177d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
51187d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
51197d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
51207d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51217d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
51227d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
51237d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
51247d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
51257d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
51267d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
51277d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51287d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
51297d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51307d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
51317d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
51327d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
51337d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
51347d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
51357d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
51367d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
51377d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
51384e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
51397d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
51404e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
5141f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
51420265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
51437d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
51447d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
5145f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
5146f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5147f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5148f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5149f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
5150f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5151f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5152f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5153f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5157f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
5158f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5159f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5160f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5161f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5162f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5163f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5164f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5165f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5166f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5167f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5168f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5169f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5170f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
5171f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5172f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5173f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5174f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5177f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
5179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5182f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5184f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
5185f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5186f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5187f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
5188f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5190f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5191f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5192f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5193f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5195f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
5196f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5197f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5200f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
5201f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5202f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5203f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5204f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5205f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5206f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5207f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5208f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5209f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
5210f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5211f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5212f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5213f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
5214f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5215f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
5216f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
5217f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5218f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5219f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5220f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
5222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5224f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
5226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5227f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
5228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
5229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
5230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5231f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
5233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
5237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
5238f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
5242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5243f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
5244f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5245f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5246f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5247f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
5248f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5249f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
5250f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
5251f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5252f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
5253f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
5254f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5255f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
5256f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5257f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
5258f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5259f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5260f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5261c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
5262f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5263f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5264f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5265f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
5266c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
5267c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
5268f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5269f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
5270c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
5271f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5272f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5273c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
5274f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5275f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
5276c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
5277c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
5278c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
5279c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
5280c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
5281c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5282c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
5283c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
5284c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5285f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
5286f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
5287f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5288f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5289f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
5290c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
5291f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5292f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
5293f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5294f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
5295f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5296f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5297f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
5298f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
5299f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5300f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5301c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
5302f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5303f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5304f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5305f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
5306f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
5307f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
5308f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
5309f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5310f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
5311f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
5312f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5313f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
5314f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
5315f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5316f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
5317c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
5318c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5319c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
5320c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
5321f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
5323f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
5324f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
5325f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
5326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5327f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
5328f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
5329f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5330f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
5331f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5332f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
5333f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
5334f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(
5335f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
5336f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
5337f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5338f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5339f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5340c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
5341c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
5342c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
5343c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
5344c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
5345c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
5346c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
5347c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
5348c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
5349c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
5350c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
5351c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
5352c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
5353c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
5354c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
5355c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
5356c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
5357c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
5358f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
5359f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
5360f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
5361f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
5362f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
5363f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5364f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5365f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
5366f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
5367c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
5368f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5369f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
5370f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
5371f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5372f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
5373f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId1 = createRawContactWithName();
5374f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
5375f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
5376f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
5377f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
5378f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5379f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5380f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId2 = createRawContactWithName();
5381f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
5382f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
5383f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
5384f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
5385f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5386f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5387f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
5388f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
5389f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
5390f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
5391f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
5392f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
5393f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
5394f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
5395f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
5396f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
5397f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5398f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
5399f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
5400f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId3 = createRawContactWithName();
5401f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
5402f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
5403f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
5404f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
5405f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
5406f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
5407f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
5408f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
5409f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
5410f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5411c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
5412c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
5413c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
5414c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long rawContactId4 = createRawContactWithName(socialAccount);
5415c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
5416c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
5417c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
5418c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
5419c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
5420c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
5421c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
5422c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
5423c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
5424f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
5425f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
5426f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
5427f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5428f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
5429f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
5430f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5431f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
5432f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5433f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
5434f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
5435f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
5436f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5437f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5438f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
5439f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
5440f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
5441f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5442f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
5443f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5444f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
5445f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
5446f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
5447f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
5448f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5449f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
5450f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
5451c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
5452c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
5453c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
5454c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
5455c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
5456c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
5457f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5458f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5459d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
5460d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
5461d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
5462d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5463d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
5464d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.switchToProfileMode();
5465d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
5466d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5467d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
5468d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
5469d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
5470d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
5471d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
5472d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
5473d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
5474d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
5475d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
5476d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
5477d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
5478d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
5479d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5480d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
5481d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
5482d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
5483d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
5484d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
5485d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
5486d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
5487d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
5488d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
5489d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5490d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
5491d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
5492d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
5493d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5494d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
5495d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.switchToProfileMode();
5496d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
5497d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5498d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
5499d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5500d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
5501d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
5502d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
5503d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
5504d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
5505d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5506d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
5507d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
5508d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
5509d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
5510d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5511d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
5512d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
5513f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
5514f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long rawContactId = createRawContactWithName();
5515f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5516f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5517f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5518f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
5519f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5520f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
5521f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
5522f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5523f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
5524f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
5525f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
5526f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
5527f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5528f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
5529f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
5530f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
5531f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
5532f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
5533f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
5534f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5535f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
5536f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertInputStreamContent(loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
5537f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
5538f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5539f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
55404e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
55414e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId1 = createRawContactWithName();
55424e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
55434e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long rawContactId2 = createRawContactWithName();
55444e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
554547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
554647fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
55474e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55484e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
55494e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
55504e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
55514e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55524e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
55534e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
55544e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55554e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
55564e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55574e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
55584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
55594e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
55604e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55614e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
55624e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
55634e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55644e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
55654e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
55664e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
55674e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55684e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
55694e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
55704e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55714e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
55724e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
55734e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
55744e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
55754e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
55766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
55776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId1 = createRawContact(new Account("a", "a"));
55786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
55796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
55806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
55816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId2 = createRawContact(new Account("b", "b"));
55826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
55836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
55846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
55856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
55866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
55876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
55886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
55896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
55906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
55916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
55926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
55936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
55946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
55956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
55966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
55976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
55986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
55996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
56036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
56046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
56076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
56086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
56166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
56176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
56206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
56216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
56246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
56256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
56336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
56366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
56376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
56456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
56486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
56496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
56556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
56576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
56586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
56596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
56606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
56616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
56646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
56656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
56666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
56676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
56686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
56696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
56706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
56716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
56726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
56746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
56756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
56766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
56776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
56786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        long rawContactId = createRawContact(new Account("a", "a"));
56796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
56806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
56826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
56836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
56846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
56856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
56866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
56886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
56896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
56916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
56926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
56936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
56946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
56956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
56966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
56976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
56986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
56996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
57016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
57026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
57036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
57046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
57056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
57066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
57076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
57096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
57106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
57116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
57126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
57136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
57146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
57176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
57186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
57216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
57226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
57256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
57266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
57286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
57296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
57306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
57316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
5732ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
5733ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
5734ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
5735ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5736ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContact();
5737ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("James", "Sullivan");
5738ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("The Abominable", "Snowman");
5739ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mike", "Wazowski");
5740ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("randall", "boggs");
5741ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Boo", null);
5742ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Mary", null);
5743ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        createRawContactWithName("Roz", null);
5744ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5745ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
5746ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
5747ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_PRIMARY + " COLLATE LOCALIZED");
5748ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5749ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, null, "B", "J", "M", "R", "T");
5750ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
5751ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
5752ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5753ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
5754ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
5755ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
5756ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5757ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", null);
5758ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
5759ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
5760ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5761ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5762ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
5763ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
5764ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
5765ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
5766ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5767ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5768ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
5769ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
5770ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
5771ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
5772ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
5773ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
5774f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
5775f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
5776f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
5777f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
5778f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
5779f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
5780f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
5781f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
5782f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
5783f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
5784f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
5785f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
5786f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5787f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5788f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
5789f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
5790f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
5791f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
5792f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5793f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5794f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
5795f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
5796f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
5797f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
5798f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
5799f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
5800f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
5801f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
5802f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
58035fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
58045fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
58055fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
58065fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
58075fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
58085fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
58095fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
58105fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
58115fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
58125fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
58135fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
58145fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
58155fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
5816f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
5817f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
5818e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
5819e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
5820e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
5821e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
5822e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5823e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
5824e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
5825e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5826e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5827e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5828e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5829e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5830e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
5831e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
5832e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
5833e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
5834e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5835e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
5836e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
5837e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
5838e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
5839e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri insertUri = maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, blue);
5840e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
5841e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
5842e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
5843e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
5844e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
5845e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
5846e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
5847e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
58483826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
58493826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
58503826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
58513826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
58523826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
58533826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        long rawContactId = createRawContact();
58543826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
58553826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
58563826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
58573826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
58583826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
58593826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
58603826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
58613826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
5862bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{ACCOUNT_1});
58633826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{ACCOUNT_1});
58643826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
5865bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
58663826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
58673826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
58683826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
58693826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
58703826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
587109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
587209c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
587309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
587409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
58753826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
587609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
587709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
587809c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
5879b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
5880743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
5881b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
5882b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
5883b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
5884b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
5885b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
5886b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
5887b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
5888b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
5889b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
5890b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
5891b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
5892b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
589342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
589442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
589542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
589642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
589742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
589842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
589942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
590042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
590142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
590242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
590342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
590442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
590542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
590642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
590742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
590842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
590942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
591042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
591142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
591242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
591342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
591442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
591542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
591642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
591742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
591842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId1 = createRawContact(mAccount, RawContacts.SOURCE_ID, "4:12");
591942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId1, "John", "Doe");
592042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
592142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long rawContactId2 = createRawContact(mAccount, RawContacts.SOURCE_ID, "3:4%121");
592242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        insertStructuredName(rawContactId2, "Jane", "Doh");
592342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
592442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
592542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
592642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
592742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
592842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
592942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
593042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
593142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
593242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
593342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
593442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
593542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
593642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
593742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
593842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
593942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
594042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
594142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
594242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
594342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
594442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
594542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
594642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
594742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
594842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
594942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
595042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
595142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
595242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
595342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
595442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
595542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
595642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
595742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
595842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
595942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
596042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
596142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
596242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
596342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
596442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
596542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
596642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
596742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
596842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
596942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
597042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
597142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
597242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
597342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
597442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
597524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
597624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
597724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
597824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
597924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
598024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
598124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
598224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
598324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
598424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
598542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
598642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
598742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
598842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
598942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
599042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
599142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
599242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
599342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
599442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
599542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
599642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
599742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
599842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
599942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
600042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
600142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
600242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
600342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
600442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
600542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
600642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
600742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
600842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
600942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
601042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
601142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
601224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
601324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
601424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
601542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
601642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
601742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
601842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
601942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
602042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
602142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
602242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
602342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
602442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
602542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
602642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
602742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
602842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
602942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6030dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
6031dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6032dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6033dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
6034dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
6035dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6036dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccountTwo);
6037dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(null);
6038dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6039dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6040dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6041dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6042dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6043dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6044dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6045dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6046dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6047dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6048dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6049dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6050dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6051dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6052dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
6053dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
6054dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6055dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6056dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6057dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6058dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6059dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6060dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
6061dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6062dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6063dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount);
6064dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo);
6065dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
6066dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null);
6067dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6068dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6069dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6070dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6071dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6072dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6073dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
6074dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6075dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6076dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6077dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6078dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6079dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
6080dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
6081dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
6082dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
6083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
6084dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
6085dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
6086dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6087dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccount, RawContacts.STARRED, "1");
6088dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r4 = createRawContact(mAccountTwo, RawContacts.STARRED, "1");
6089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r5 = createRawContact(mAccountTwo);
6090dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r6 = createRawContact(null, RawContacts.STARRED, "1");
6091dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r7 = createRawContact(null);
6092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6098dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
6099dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6100dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6101dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6102dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6103dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6104dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6105dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6106dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6107dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6108dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6109dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6110dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6111dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6112dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6113dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6114dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6115dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6116dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6117dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6118dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6119dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6120dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6121dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6122dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
6123dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
6124dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
6125dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6126dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6127dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6128dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6129dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6130dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6131dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6132dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6133dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6134dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6135dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6136dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
6137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6141dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6142dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
6143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6144dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6145dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6146dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6147dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6148dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6149dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6150dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6151dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6152dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6153dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6154dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6155dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6156dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
6157dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6158dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
6159dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
6160dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
6161dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount, RawContacts.STARRED, "1");
6162dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6163dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
6164dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6165dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6166dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6167dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6168dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6169dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6170dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6171dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6172dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6173dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6174dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6175dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6176dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6177dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
6178dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6179dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6180dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6181dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6182dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6183dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
6184dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
6185dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
6186dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
6187dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
6188dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6189dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6190dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6191dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6192dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6193dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6194dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6195dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6196dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6197dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6198dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6199dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6200dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
6201dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6202dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6203dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6204dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6205e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
6206dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
6207dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6208dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
6209dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
6210dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
6211dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
6212dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
6213dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6214dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6215dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6216dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6217dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6218dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6219dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6220dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6221dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6222dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6223dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6224dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
6225dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
6226dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
6227dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6228dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6229dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6230dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6231dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
6232dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6233dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
6234dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
6235dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
6236dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r1 = createRawContact(mAccount);
6237dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r2 = createRawContact(mAccount);
6238dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long r3 = createRawContact(mAccountTwo);
6239dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6240dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6241dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6242dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6243dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6244dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
6245dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6246dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
6247dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
6248dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
6249dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
6250dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6251dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6252dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6253dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6254dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6255dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6256dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6257dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6258dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6259dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6260dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6261dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6262dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6263dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6264dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
6265dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
6266dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
6267dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6268dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6269dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6270dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
6271dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6272dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6273dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6274dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
6275dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
6276dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
6277dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6278dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6279dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6280dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6281dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6282dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6283dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6284dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
6285dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6286dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6287dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6288dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6289dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6290dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6291dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
6292dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
6293dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
6294dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
6295dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6296dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
6297dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6298dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6299dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6300dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
630197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
630297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
630397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
630497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
630597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
630697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
630797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
630897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
630997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
631097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
631197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
631297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
631397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
631497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
631597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
631697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
631797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
631897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId = createRawContact();
631997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
632097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
632197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
632297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
632397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
632497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
632597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
632697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
632797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
632897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
632997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
633097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
633197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
633297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
633397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
633497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
633597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
633697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId1 = createRawContact();
633797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
633897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
633997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
634097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long rawContactId2 = createRawContact();
634197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
634297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
634397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
634497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
634597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
634697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
634797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
634897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
634997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
635097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
635197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
635297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
635397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
635497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
635597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
635697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
63577a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
63587a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
63597a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
63607a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
63617a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
63627a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
636317a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
63647a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
63657a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
63667a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
63677a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
63687a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
63697a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
63707a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
63717a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
63727a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
63737a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
63747a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
63757a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
63767a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
63777a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
63787a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
63797a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
63807a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
63817a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
63827a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
63837a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
638455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
63857a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
63867a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
63877a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
63887a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
63897a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
63907a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
63917a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
63927a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
63937a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
63947a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
63957a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
6396dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
6397dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = mResolver.query(maybeAddAccountQueryParameters(Data.CONTENT_URI, account),
6398dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
6399dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
6400dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
6401dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
6402dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6403dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
640442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
640542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
6406bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
640742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
640842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
6409bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
6410bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
6411bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
6412bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
6413bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
6414bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
6415bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
641642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
6417bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
6418bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
641942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
642042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
642142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
642242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
642342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
642442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6425f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
6426f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
6427f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
6428f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6429f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
64304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
64314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
6432aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
643324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
643424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
643524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
643624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
643724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
643824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
643924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
644048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
644124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
644248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
644348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
644448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
644548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
6446aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
644748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
6448aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
644948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        insertStructuredName(rawContactId, firstName, givenName);
645048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
645148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
645248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
645324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
645424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
645524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
645624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
645724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
645824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        insertStructuredName(rawContactId, firstName, givenName);
645924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
646024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
646124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
646248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
6463aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
646424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
646524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
646624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
646724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
646824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
646924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
647024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
64714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
64724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
64734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
64744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
647524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
647624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
647724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
647824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
647924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
64804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
64814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
64824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
64834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
64849dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
64859dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
64869dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
64879dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
64889dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
64899dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
64904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
6491aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
64925d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
64934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
64944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
64954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
64964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
649724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
649848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
64994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
65004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
650124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
650224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
650324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
650424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
650524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
650624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
650724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
650824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
650924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
651024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
651124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
651224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
651324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
651424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
651524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
651624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
651724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
651824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
651924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
652024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
652124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
652224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
652324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
652424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
652524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
652624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
652724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
652824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
65294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
65304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
65314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
65324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
65334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
65344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
65354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
65364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
65374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
65384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
65394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
65404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
65414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
65424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
65434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
65444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
65454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
65464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
65474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
65484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
65494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
65504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
65514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
65524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
65534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
65544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
65554928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
65564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
65574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
65584928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
65594928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
65604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
65614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
65624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
65634928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
65644928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
65654928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final Uri feedbackUri = DataUsageFeedback.FEEDBACK_URI.buildUpon()
65664928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendPath(String.valueOf(dataId))
65674928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
65684928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                .build();
65694928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertNotSame(0, mResolver.update(feedbackUri, new ContentValues(), null, null));
65704928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
65714928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
65724928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
65734928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
6574d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
6575