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
19dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onukiimport static com.android.providers.contacts.TestUtils.cv;
20dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
2170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wongimport android.accounts.Account;
22d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderOperation;
23d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderResult;
248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport android.content.ContentResolver;
25d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentUris;
26d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentValues;
279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.content.Entity;
2833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.content.EntityIterator;
2942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport android.content.res.AssetFileDescriptor;
30d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.database.Cursor;
31d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.net.Uri;
32c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoroimport android.os.AsyncTask;
33c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract;
34d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
35e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Callable;
36216c434537d05a691add4e22ba3a9d958c976c1eYorke Leeimport android.provider.ContactsContract.CommonDataKinds.Contactables;
37dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
38dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
39dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
40dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
41dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
42dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
43e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
44dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
45dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
46ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikovimport android.provider.ContactsContract.ContactCounts;
47c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.provider.ContactsContract.Data;
4946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawaimport android.provider.ContactsContract.DataUsageFeedback;
50dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.Directory;
515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
52f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.DisplayPhoto;
537a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
543cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.ContactsContract.Groups;
554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
5781fea08280784b319b936a3506788d595c6ce2adYorke Leeimport android.provider.ContactsContract.PinnedPositions;
5824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
5909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
6033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6162318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
62916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikovimport android.provider.ContactsContract.SearchSnippetColumns;
6389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
6482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
66f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
67dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
687d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
69d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
70f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
7138210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
7238210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.internal.util.ArrayUtils;
7338210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
74a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.ContactsColumns;
7538210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
7638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
7738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
78a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
7938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables;
808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.CommonDatabaseUtils;
818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.ContactUtil;
828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DataUtil;
838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DatabaseAsserts;
848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DeletedContactUtil;
858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.RawContactUtil;
868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.TestUtil;
8738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.tests.R;
8838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Lists;
8938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Sets;
90d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
9142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
9242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
93f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport java.util.HashSet;
983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
1009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport java.util.Set;
1015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
102d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
103d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
104d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
105d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
106d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
10723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki   adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
10823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki           com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
109d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
110d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
111d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
112d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
113d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
1148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private static final String TAG = ContactsProvider2Test.class.getSimpleName();
11547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
116dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
117dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
118dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
119dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
120dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
121dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
122dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
123dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
124dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
125dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
126a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
127a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
128a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
129a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
13381fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
134dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
135dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
136f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1373d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1383d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
139dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
140dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
14224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
143dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
144dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
147dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
148dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
149dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
150dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
151dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
1528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
153dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
154dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
155dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
15663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentProjection() {
15763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI, new String[]{
15863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
15963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
16063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
16163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
16263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
16363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
16463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
16563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
166a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
167a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
168a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
169a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
17063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
17163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
17263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
17381fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
17463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
17563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
17663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
17763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
17863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
17963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
18063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
18163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
18263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
18363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
18463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
18563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
18663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
18763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
18863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
18963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
19063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
19163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
1928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
19363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
19463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
19563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
19663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
19763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
19863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentPhoneOnlyProjection() {
19963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI.buildUpon()
20063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build(),
20163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                new String[] {
20263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
20363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
20463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
20563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
20663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
20763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
20863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
20963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
210a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
211a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
212a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
213a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
21463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
21563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
21663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
21781fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
21863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
21963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
22063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
22163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
22263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
22363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
22463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
22563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
22663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
22763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
22863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
22963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
23063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
23163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
23263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
23363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
23463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
23563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
2368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
23763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
23863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
23963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.NUMBER,
24063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.TYPE,
24163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.LABEL,
242f6de5a9d1418b0d7f4119d4204818ab3a0fe4fa2Yorke Lee                Phone.IS_SUPER_PRIMARY,
243a89aa7533a14b143b55bf4a29d284152ab9278a5Yorke Lee                Phone.CONTACT_ID
24463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
24563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
24663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
251dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
252dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
253dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
254dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
255dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
257dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
258a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
259a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
260a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
261a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
264dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
26581fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
267dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
268f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2693d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2703d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
272dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
273dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
27424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
278dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
283dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
2848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
28530cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
288dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
29543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
29643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
298dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
29924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
309dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
310a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_PRIMARY,
311a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
312a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
313a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
31981fea08280784b319b936a3506788d595c6ce2adYorke Lee                RawContacts.PINNED,
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
326dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
327dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
328dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
329dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
345dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
346dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
347dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
348dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
349dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
350dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
351dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
352dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
353dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
354dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
355dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
356dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
357dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
358dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
359dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
360dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
361dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
362dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
363dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
364216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
365216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
366dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
367dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
36843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
36943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
370dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
371dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
372dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
373dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
37424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
375dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
376dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
377dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
378dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
379dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
380dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
381dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
382dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
383a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
384a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
385a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
386a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
387dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
388dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
389dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
39081fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
391dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
392dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
393f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3953d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
396dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
397dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
398dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
399dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
400cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
401dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
402dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
403dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
404dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
405dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
406dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
407dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
409dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
410dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
411dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
412dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
413dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
414dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
415dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
416dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
417dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
418dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
419dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
420dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
421dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
422dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
423dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
424dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
425dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
426dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
427dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
428dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
445dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
446dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
449216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
450216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
45124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
460a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
461a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
462a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
463a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
466dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
46781fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
470f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4713d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4723d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
473cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
482dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
483dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
485dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
486dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
487dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
488dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
489a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
490a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
491a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
492a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
493a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
494a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
495a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
496a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
497a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
498a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
499a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
500a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
501a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
502a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
503a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
504a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
505a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
506a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
507a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
508a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
509a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
510a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
511a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
512a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
513a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
514a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
515a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
516a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
517a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
518a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
519a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
520a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
521a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
522a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
523a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
524a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
525a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
526a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
527a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
528a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
529a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
530a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
53143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
53243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
533a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
534a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
535a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
536a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
537a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
538a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
539a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
540a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
541a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
542a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
543a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
544a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
545a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
546a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
547a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
548a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
549a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
550a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
551a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
552a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
553a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
554a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
555a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
556a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
55781fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
558a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
559a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
560f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
5613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
5623d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
563a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
564a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
56524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
566a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
567a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
568cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
569a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
570a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
571a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
572a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
573a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
574a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
575a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
5768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
577a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
578a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
579a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
580a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
581dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
587dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
58843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
58943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
599dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
60024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
614dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
618dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
619dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
620dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
621dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
622dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
623dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
624dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
625dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
626dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
627dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
628dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
629dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
630dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
631dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
632dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
633dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
634dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
635dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
636dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
637dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
638dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
639dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
6403d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
6413d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
642dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
643dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
644dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
645dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
646dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
647dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
6482530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
649dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
650dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
651dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
652dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
653dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
654dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
655dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
656dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
65743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
65843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
659dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
660dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
661dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
662dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
663dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
664dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
665dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
666dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
667dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
668dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
669dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
670dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
671dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
672c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
673dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
674dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
675dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
676dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
677dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
678dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
679dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
680dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
681dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
682dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
683dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
684dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
68543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
68643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
687dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
688dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
689dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
690dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
691dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
692dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
693dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
694dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
695dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
696dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
697dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
698dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
699dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
700c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
701dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
702dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
703dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
704dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
705dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
706dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
70718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
708dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
709dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
710dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
711dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
712dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
713dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
714dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
715dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
716dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
717dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
718dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
719dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
720dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
721dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
722dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
723dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
724f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET,
725dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
726dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
727dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
728dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
729dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
730dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
731dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
732dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
733dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
734dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
735dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
736dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
737dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
738dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
739dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
740dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
741dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
742dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
743dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
744dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
745dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
746dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
747dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
748dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
749dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
750dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
751dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
752dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
753dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
754dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
755dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
756dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
757dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
758dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
759dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
760dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
761778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
762778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
763dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
764dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
765dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
7663cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
7673cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
7683cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
7703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
7719d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(RawContacts.DATA_SET, "ds");
7723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
7733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
7743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
7753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
7763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
7773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
7783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
7793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
7803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
7813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
7823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
7833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
7843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
7853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
7874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
7883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
7904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
79181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
7923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
7933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7942149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
7952149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
7962149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
7982149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
7992149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
8002149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8012149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8022149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
8032149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8042149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
8052149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
8062149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8072149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8082149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8092149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8102149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
8112149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
8122149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8132149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8142149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8152149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
8162149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
8172149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
8182149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8192149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8202149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8212149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
8222149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
8232149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
8242149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
8252149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
8262149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8272149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8282149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8292149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
8302149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8312149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8322149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8332149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
8342149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8352149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8362149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
8372149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8382149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
839a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
840a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
841a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
842a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
843a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
845a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
846a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8475d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
848a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
850a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
851a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
852a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
853a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
854a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
855a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
856a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
857a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
858a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
859a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
860a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
861a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
862a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
863a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
864a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
865a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
867a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
868a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8695d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
870a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
872a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
873a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
874a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
875a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
876a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
877a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
878a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
879a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
880a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
881a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
882a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
883a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
884a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
885a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
886a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
887a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
888a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
889a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
890a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
891a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
892a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
893a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
894a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
895a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
896a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
897a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
898a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
899a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
900a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
901a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
902a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
903a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
904a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
905a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
906a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
907a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
908a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
909a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
910a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
911a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
912a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
913a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
914a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
915a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
916a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
917a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
918a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
919a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
920a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
921a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
922a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
923a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
924a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
925a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
926a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
927a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
928a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
929a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
930a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
931a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
932a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
933a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
934a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
935a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
936a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
937a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
938a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
939a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
940a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
941a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
942a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
943a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
944a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
945a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
946a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
947a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
948a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
949a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
950a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
951a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
952a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
953a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
954a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
955a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
956a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
9573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
9588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
9594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
9614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
9624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
9634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
9644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
9664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
9674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
9684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
9704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
9724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
9734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
9744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
9754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
9764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
9784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
9794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
9804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
98181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
9824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
9833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
98489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
98589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
98689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
9878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
9888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
9898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
9908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doe");
99189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(dataUri1, account1);
9938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(dataUri2, account2);
99489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
99589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
99689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
99789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
9997d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
10003cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
10014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
10024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
10034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
10044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
10054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
10064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
10084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
10094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
10124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
10134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
10183cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
10214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
10224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
10234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
10244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
10274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
10284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
10294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
10304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
103148828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
10324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
10334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1035cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    public void testPhonesWithMergedContacts() {
10368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1037cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "123456789", true);
1038cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
1040cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "123456789", true);
1041cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10420992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
10430992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki                rawContactId1, rawContactId2);
10440992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        assertNotAggregated(rawContactId1, rawContactId2);
10450992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki
1046cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1047cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "123456789");
1048cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1049cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Phone.NUMBER, "123456789");
1050cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10510992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // There are two phone numbers, so we should get two rows.
1052cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
1053cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10540992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now set the dedupe flag.  But still we should get two rows, because they're two
10550992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // different contacts.  We only dedupe within each contact.
10568ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Phone.CONTENT_URI.buildUpon()
10578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
10588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
10598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, new ContentValues[] {values1, values1});
10608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10610992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now join them into a single contact.
1062cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
1063cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa                rawContactId1, rawContactId2);
1064cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1065cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertAggregated(rawContactId1, rawContactId2, "123456789");
1066cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10670992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Contact merge won't affect the default result of Phone Uri, where we don't dedupe.
10688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
10698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10700992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now we dedupe them.
10718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values1);
1072cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    }
1073cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1074904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    public void testPhonesNormalizedNumber() {
10758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver);
1076904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1077904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Write both a number and a normalized number. Those should be written as-is
1078904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final ContentValues values = new ContentValues();
1079904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.RAW_CONTACT_ID, rawContactId);
1080904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1081904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1234");
1082904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "5678");
1083904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.TYPE, Phone.TYPE_HOME);
1084904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1085904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
1086904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
108710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the lookup table.
1088904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1089904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1090904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1091904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1092904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
109310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the data table.
109410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
109510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1234", Phone.NORMALIZED_NUMBER, "5678")
109610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
109710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1098904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace both in an UPDATE
1099904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1100904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "4321");
1101904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1102904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1103904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1104904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1105904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1106904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "4321"), null, null));
1107904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1108904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1109904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1110904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1111904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
111210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
111310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "4321", Phone.NORMALIZED_NUMBER, "8765")
111410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
111510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1116904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NUMBER ==> NORMALIZED_NUMBER will be inferred (we test that by making
1117904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // sure the old manual value can not be found anymore)
1118904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
111910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "+1-800-466-5432");
1120904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1121904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1122904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
112310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1124904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1125904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1126904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1127904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
112810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
112910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
113010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
113110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1132904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NORMALIZED_NUMBER ==> call is ignored, things will be unchanged
1133904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1134904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1135904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1136904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1137904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
113810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1139904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1140904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1141904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
114210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
114410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
114510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
114610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Replace NUMBER with an "invalid" number which can't be normalized.  It should clear
114810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // NORMALIZED_NUMBER.
114910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 1. Set 999 to NORMALIZED_NUMBER explicitly.
115110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
115210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "888");
115310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NORMALIZED_NUMBER, "999");
115410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
115510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(1,
115710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
115810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
116010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "888", Phone.NORMALIZED_NUMBER, "999")
116110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
116210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
116310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 2. Set an invalid number to NUMBER.
116410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
116510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "1");
116610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
116710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
116810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(0,
116910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
117010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
117110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
117210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1", Phone.NORMALIZED_NUMBER, null)
117310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
1174904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    }
1175904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
11764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
1177e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
1178e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1179e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1180e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
1181e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
1182e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
1183e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1184e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
1185e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
1186e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1187e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
1188e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
1189e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
1190e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
1191e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
1192e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
1193e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
1194e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
11958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot",
11968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale", TestUtil.ACCOUNT_1);
11975e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
11985e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Chilled",
12008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Guacamole", TestUtil.ACCOUNT_2);
12012a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
120258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
120358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
12045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1205e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
12064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
12074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
12084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
12095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
12114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
12125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
12134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1214e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
12155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
12165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1217e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
12185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
12195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1220e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
12215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
122245d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
1223e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
122445d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
122558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
122658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
122758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
122858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
122958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
123058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
123158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
123258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
123358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
123458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
123558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
123658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
123758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
123858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
123958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
124058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
124158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
124258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
124358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
124458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
124558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
124658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
1247e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
1248dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValues(filterUri6, new ContentValues[]{values1, values2, values3});
1249e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1250e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
1251e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1252e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1253e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1254e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1255e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1256e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1257e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1258e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1259e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1260e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1261e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1262e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1263e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1264e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1265e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1266e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1267e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1268e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1269e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1270e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1271e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1272e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1273e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1274e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1275e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1276e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1277e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1278e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1279e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1280e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1281e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
128258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
12834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
12844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12854c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    public void testPhonesFilterSearchParams() {
12868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "Dad", null);
12874c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid1, "123-456-7890");
12884c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "Mam", null);
12904c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid2, "323-123-4567");
12914c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12924c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // By default, "dad" will match both the display name and the phone number.
12934c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // Because "dad" is "323" after the dialpad conversion, it'll match "Mam" too.
12944c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12954c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad").build(),
12964c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890"),
12974c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
12984c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
12994c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13004c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13014c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
13024c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13034c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890")
13044c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13054c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
13064c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13074c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13084c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
13094c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13104c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
13114c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13124c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13134c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
1314dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
1315dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
1316dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .build()
1317dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        );
13184c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    }
13194c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
1320e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1321e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1322e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1323e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1324e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1325e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1326e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1327e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
13288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
13304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1331ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1332ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1333ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
13344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1335e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1336e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1337e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1338e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1339e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1340e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1341e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1342e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1343e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1344ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
13454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1346892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
134734984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1348e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
134934984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
13506db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13516db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // A wrong area code 799 vs 800 should not be matched
13526db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "7994664411");
13536db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
1354892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1355892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1356892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1357892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1358892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1359892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1360892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1361892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1362892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1363892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1364892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1365892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1366892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1367892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1368892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1370892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1371892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1372892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1373892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1374892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1375892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1376892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1377892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1378892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1379892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1380892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1381892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13826db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with wrong area code
13836db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "649 861 0000");
13846db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13856db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13866db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digits in mistyped area code
13876db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "5 861 0000");
13886db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13896db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13906db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digit in mistyped area code
13916db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "65 861 0000");
13926db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13936db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
1394892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1395892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1396892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1397892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1398892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1399892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1400892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
14018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot1", "Tamale");
1402892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1403892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1404892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1405892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1406892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1407892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1408892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1409892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1410892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1411892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1412892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1413892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1414892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1415892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1416892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1417892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1418892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1419892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1420892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
14218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot2", "Tamale");
1422892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1423892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1424892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1425892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1426892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1427892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1428892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1429892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1430892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1431892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1432892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
14334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
143556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
14366db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Checks the logic that relies on phone_number_compare_loose(Gingerbread) as a fallback
14376db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        //for phone number lookups.
143856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
143956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
144056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
144156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
144256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
144356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
144556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
144656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
144756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
144856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
144956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
145056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
145256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
145356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
145456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
14556db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Number with international (+972) prefix should also match.
14566db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(1, getCount(Uri.withAppendedPath(
14576db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee                PhoneLookup.CONTENT_FILTER_URI, "+97297427289"), null, null));
145856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
146056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
146156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
146256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
146456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
146556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
146656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
146856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
146956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
147056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
147156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
147356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
147456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
147556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
147756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
147856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
147956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
148156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
148256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
148556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
148856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
149056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
149156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
149256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
149356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
149456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
149556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
149656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
149756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
149856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1499a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    public void testPhoneLookupUseStrictPhoneNumberCompare() {
1500a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Test lookup cases when mUseStrictPhoneNumberComparison is true
1501a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
1502a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
1503a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Get and save the original value of mUseStrictPhoneNumberComparison so that we
1504a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // can restore it when we are done with the test
1505a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
1506a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
1507a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1508a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1509a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        try {
1510a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            String fullNumber = "01197297427289";
1511a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            ContentValues values = new ContentValues();
1512a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.CUSTOM_RINGTONE, "d");
1513a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1514a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            long rawContactId = ContentUris.parseId(
1515a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    mResolver.insert(RawContacts.CONTENT_URI, values));
15168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
1517a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, fullNumber);
1518a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "5103337596");
1519a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "+19012345678");
1520a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for full number
1521a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1522a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
1523a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1524a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra digit at the front
1525a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1526a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
1527a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for mispelled area code
1528a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1529a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
1530a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1531a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with dashes
1532a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1533a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
1534a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1535a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with international code
1536a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1537a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
1538a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1539a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1540a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra 0 in front
1541a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1542a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
1543a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1544a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1545a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for different country code
1546a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1547a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
1548a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1549a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        } finally {
1550a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // restore the original value of mUseStrictPhoneNumberComparison
1551a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // upon test completion or failure
1552a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
1553a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        }
1554a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    }
1555a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1556653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1557653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1558653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1559653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1560653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
15618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1562653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1563653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1564653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1565ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
1566ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
1567ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
1568653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1569653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1570653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1571653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1572653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1573ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1574ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
1575653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1576653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1577653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1578653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1579653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1580653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1581ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1582653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1583653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1584653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1585653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1586653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1587653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1588ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1589ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
159081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1591653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1592653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1593e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
1594e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
15958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Meghan", "Knox");
1596e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
1597e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
1598e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
15998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
1600e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
1601e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
1602e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
1603e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1604e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1605e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
1606e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
1607e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
1608e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1609e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
1610e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
1611e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
1612e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
1613e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1614e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
1615e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
1616e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
1617e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
1618e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1619e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
1620e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
1621e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1622e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
1623e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
1624e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1625e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1626e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
1627e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
1628e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1629e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
16304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
16334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
16344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
16354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
16364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
16374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
16398ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
16404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
16428ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
16438ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
16444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16458ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
16464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
16474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
16484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
16494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
16504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
16524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
16544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
16554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
16564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
16574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
16584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
16594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
16604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16618ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
166248828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
16648ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
16668ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
16678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
16688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
16698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
16708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
16728ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
16738ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
16748ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16758ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
16768ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16778ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
16788ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
16798ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
16808ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16818ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
16828ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16838ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
16848ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
16858ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
16868ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
16874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16895e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
16908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale");
16914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
16924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16935e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
16944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
16964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
16984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
17004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
17014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
170208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
170308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
170408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
170508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
170608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
17074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
17084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
17095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
17108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
17125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
17175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
17185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
17205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
17215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
17225e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
17235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
17245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
17255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
17265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
17275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
17295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
17305e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1731155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
17325e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
17335e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17341e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
17355e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
17365e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17375e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
17385e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
17395e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
17405e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17417d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1742c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1743c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1744c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
17458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1746c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1747c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1748c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1749c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1750c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1751c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1752c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1753c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1754c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1755c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1756c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1757dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, new ContentValues[]{v1, v2, v3});
1758c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1759c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1760c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1761c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1762c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1763c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
17648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1765c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1766c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1767c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1768c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1769c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1770c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1771c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1772c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1773c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1774c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1775c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1776c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
17777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
17787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
17797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
17807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
17818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
17827d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
17838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_2);
17847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
17857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
17867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
17877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
17887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
17897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
17928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_1.type)
17937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
17947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
17957d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
17988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_2.type)
17997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
18007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
18017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
18027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
18037d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
18048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
18057d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
1806dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri3, new ContentValues[]{v1, v2});
18077d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
18087d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
18098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
18107d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
18117d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
18127d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
18137d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
1814dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1815dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test emails with the same domain as primary account are ordered first.
1816dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1817dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    public void testEmailFilterSameDomainAccountOrder() {
1818dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Account account = new Account("tester@email.com", "not_used");
18198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, account);
1820dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@testemail.com");
1821dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@email.com");
1822dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1823dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1824dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account1@email.com");
1825dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1826dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
1827dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, account.name)
1828dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, account.type)
1829dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .build();
1830dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri1, v2, v1);
1831dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1832dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1833dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1834dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test "default" emails are sorted above emails used last.
1835dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1836c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterSuperPrimaryOverUsageSort() {
18378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1838dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1839dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1840c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true, true);
1841dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1842dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Update account1 and account 2 to have higher usage.
1843dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1844dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1845dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1846dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1847dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1848dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1849dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1850dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1851dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1852dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1853dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, v3, v1, v2);
1854dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1855dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1856c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    /**
1857c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * Test primary emails are sorted below emails used last.
1858c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     *
1859c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * primary may be set without super primary.  Only super primary indicates "default" in the
1860c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * contact ui.
1861c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     */
1862c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterUsageOverPrimarySort() {
18638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1864c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1865c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1866c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true);
1867c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1868c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Update account1 and account 2 to have higher usage.
1869c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1870c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1871c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1872c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1873c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1874c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1875c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1876c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1877c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1878c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1879c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        assertStoredValuesOrderly(filterUri, v1, v2, v3);
1880c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    }
1881c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
188246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
188346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
18848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
18854928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
18864928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
1887dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
18888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
18894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
18904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
18914928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
18924928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
189346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
189446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
189546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
189646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
189746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
189846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
189946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
190046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
190146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
190246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
190346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
190446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
190546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
190646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
190746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
190846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
190946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
191046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
191146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
191246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
191346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
191446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
191546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
191646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
191746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
191846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
19194928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
192046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1921dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
1922dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId1,
1923dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0
1924dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
1925dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId2,
1926dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 1
1927dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
1928dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
1929dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
1930dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // account3@email.com should be the first.
193146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
193246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
193346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
193446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1935f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1936f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1937f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1938f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1939f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
19408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1941f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1942f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1943f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1944f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1945f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1946f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1947f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1948f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1949f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1950f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1951f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1952f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1953f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1954f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1955f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1956f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1957f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1958f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1959f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1960f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1961f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1962f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1963f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1964f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1965f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1966f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1967f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1968f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1969f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1970f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1971f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1972f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1973f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1974f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1975f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1976f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1977f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1978f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1979f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1980f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1981f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1982f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1983f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1984f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1985f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1986f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1987f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1988f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1989f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1990f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1991f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1992f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1993f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1994f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1995f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1996f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1997f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1998f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1999f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
20004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
20018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Alice", "Nextore");
20024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
20038ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
20044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20058ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
20064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
20074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
20084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
20094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
20104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
20114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
20124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
20134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20148ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
201548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
201648828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
20174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
20188ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
20208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
20218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
20228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
20238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
20248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20258ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
20268ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
20278ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
20288ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20298ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
20308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
20318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
20328ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
20338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
20348ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
20358ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
20368ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20378ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
20388ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20398ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
20408ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
20418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
20428ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
20434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
20444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testDataContentUriInvisibleQuery() {
20468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues values = new ContentValues();
20478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final long contactId = createContact(values, "John", "Doe",
20488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
20498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                        StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
20508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri uri = Data.CONTENT_URI.buildUpon().
20528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true").build();
20538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(4, getCount(uri, null, null));
20548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(contactId);
20568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(uri, null, null));
20588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
20598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesQuery() {
20618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
20628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
20638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
20658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
20668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
20688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
20708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
20718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
20728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
20738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
20758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
20778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
20788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
20798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
20808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri0 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "");
20828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri0, null, null));
20838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
20858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2);
20868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
20888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2);
20898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale@ac");
20918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2);
20928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "510");
20948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv1, cv2);
20958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "cold");
20978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri5, null, null));
20988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
21008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
21018f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri6, null, null));
21028f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21038f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Contactables.CONTENT_URI;
21048f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri7, cv1, cv2);
21058f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
21068f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21078f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesMultipleQuery() {
21088f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
21108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
21118f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
21128f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
21138f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "hot@google.com");
21148f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Cold",
21168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamago");
21178f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId2, "eggs@farmers.org");
21188f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
21208f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId3, "518-354-1111");
21218f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId3, "doeadeer@afemaledeer.com");
21228f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21238f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
21248f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21258f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21268f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
21278f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
21288f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
21298f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21308f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
21318f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21328f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21338f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
21348f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
21358f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
21368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv3 = new ContentValues();
21388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.DATA, "hot@google.com");
21418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.TYPE, Email.TYPE_HOME);
21428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.putNull(Email.LABEL);
21438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv4 = new ContentValues();
21458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Contacts.DISPLAY_NAME, "Cold Tamago");
21468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.DATA, "eggs@farmers.org");
21488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.TYPE, Email.TYPE_HOME);
21498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.putNull(Email.LABEL);
21508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv5 = new ContentValues();
21528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Contacts.DISPLAY_NAME, "John Doe");
21538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.DATA, "doeadeer@afemaledeer.com");
21558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.TYPE, Email.TYPE_HOME);
21568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.putNull(Email.LABEL);
21578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv6 = new ContentValues();
21598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Contacts.DISPLAY_NAME, "John Doe");
21608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21618f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.DATA, "518-354-1111");
21628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.TYPE, Phone.TYPE_HOME);
21638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.putNull(Phone.LABEL);
21648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
21668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2, cv3);
21688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
21708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2, cv3);
21718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tam");
21738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2, cv3, cv4);
21748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "518");
21768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv5, cv6);
21778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doe");
21798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri5, cv5, cv6);
21808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "51");
21828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri6, cv1, cv2, cv3, cv5, cv6);
21838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
21858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
21868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri7, null, null));
21878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri8 = Contactables.CONTENT_URI;
21898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri8, cv1, cv2, cv3, cv4, cv5, cv6);
21908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // test VISIBLE_CONTACTS_ONLY boolean parameter
21928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri9 = filterUri6.buildUpon().appendQueryParameter(
21938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                Contactables.VISIBLE_CONTACTS_ONLY, "true").build();
21948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv1, cv2, cv3, cv5, cv6);
21958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // mark Hot Tamale as invisible - cv1, cv2, and cv3 should no longer be in the cursor
21968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(queryContactId(rawContactId));
21978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv5, cv6);
21988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
21998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
22008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
22014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
22024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
22034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2204aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2205d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
22064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
22074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
22094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
22104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
22134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
22144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2215aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2216aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
221782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2218aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
2219ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2220ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2221ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
22224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2224a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
22254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
222648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2227aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2228d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2229aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
223048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
223148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
223248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
223348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
22343b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
22353b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
22368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, nameValues);
223748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
223848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
223982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
224048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2241ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
2242ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
22434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
224448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
22453b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
224648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2247a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
22483b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
22493b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
2250a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
22517ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22527ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
22537ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
22547ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
22557ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22567ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
22577ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22587ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
22597ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
2260a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2261a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2262a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2263a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
2264a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2265a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2266a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2267a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2268a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2269a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2271a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2272a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2273a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2274a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2275a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
2276a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2277a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2278a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
2279a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
2280a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
2281a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
2282a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
2283a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2284a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
2285a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
2286a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2287a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2288a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2289a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
2290a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2291a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2292a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2293a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2294a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2295a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2297a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2298a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2299a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2300a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2301a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
2302a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2303a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2304a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
2305a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
2306a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
2307a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
2308a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2309a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
2310a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
2311a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
23124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
23134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23142f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
23152f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
23162f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
23172f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
2318ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
23194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
23202f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
2321a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber1 = "18004664411";
23222f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
2323a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        createContact(values1, "Noah", "Tever", phoneNumber1,
23242f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
2325d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
23264928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
23274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
23284928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
2329aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
2330aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
23314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
23322f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
23332f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
23342f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
23352f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
2336d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
23374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
23389dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
2339aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
2340d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
23414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23422f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
23432f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
23442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
23452f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
23474928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
23482f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23492f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
23502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23512f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
23522f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23534928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23542f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
23554928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23562f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23572f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
23582f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23594928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
23602f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23619dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
23629dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
23639dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
23642f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
23652f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
23662f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
23679dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
23689dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
2369a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Now the 4th contact has three phone numbers, one of which is called twice and
2370a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // the other once
2371a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber4 = "18004664414";
2372a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber5 = "18004664415";
2373a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber6 = "18004664416";
2374a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber4);
2375a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber5);
2376a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber6);
2377a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values3.put(Phone.NUMBER, phoneNumber3);
2378a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values4.put(Phone.NUMBER, phoneNumber4);
2379a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2380a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber5, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2381a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber5, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2382a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber6, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2383a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2384a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Create a ContentValues object representing the second phone number of contact 4
2385a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final ContentValues values5 = new ContentValues(values4);
2386a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values5.put(Phone.NUMBER, phoneNumber5);
2387a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2388a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Create a ContentValues object representing the third phone number of contact 4
2389a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final ContentValues values6 = new ContentValues(values4);
2390a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values6.put(Phone.NUMBER, phoneNumber6);
2391a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2392a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Phone only strequent should return all phone numbers belonging to the 4th contact,
2393a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // and then contact 3.
2394a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] {values5, values6,
2395a176ed4c42330e64d0246a10374507c862cec0deYorke Lee                values4, values3});
23964928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
23974928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
23984928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
23994928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
24004928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
2401a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] {values5, values6,
2402a176ed4c42330e64d0246a10374507c862cec0deYorke Lee                values4, values3});
24034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2404a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values4.remove(Phone.NUMBER);
2405ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
24062f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
24074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
24084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
240963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testQueryContactStrequentFrequentOrder() {
241063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare test data
24118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContact(mResolver);
241263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1 = ContentUris.parseId(insertPhoneNumber(rid1, "1"));
241363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1e = ContentUris.parseId(insertEmail(rid1, "1@email.com"));
241463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContact(mResolver);
241663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did2 = ContentUris.parseId(insertPhoneNumber(rid2, "2"));
241763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContact(mResolver);
241963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did3 = ContentUris.parseId(insertPhoneNumber(rid3, "3"));
242063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContact(mResolver);
242263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did4 = ContentUris.parseId(insertPhoneNumber(rid4, "4"));
242363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid5 = RawContactUtil.createRawContact(mResolver);
242563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did5 = ContentUris.parseId(insertPhoneNumber(rid5, "5"));
242663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid6 = RawContactUtil.createRawContact(mResolver);
242863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did6 = ContentUris.parseId(insertPhoneNumber(rid6, "6"));
242963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2430d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long rid7 = RawContactUtil.createRawContact(mResolver);
2431d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long did7 = ContentUris.parseId(insertPhoneNumber(rid7, "7"));
2432d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2433d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long rid8 = RawContactUtil.createRawContact(mResolver);
2434d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long did8 = ContentUris.parseId(insertPhoneNumber(rid8, "8"));
2435d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
243663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid1 = queryContactId(rid1);
243763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid2 = queryContactId(rid2);
243863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid3 = queryContactId(rid3);
243963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid4 = queryContactId(rid4);
244063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid5 = queryContactId(rid5);
244163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid6 = queryContactId(rid6);
2442d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long cid7 = queryContactId(rid7);
2443d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long cid8 = queryContactId(rid8);
244463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Make sure they aren't aggregated.
2446d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        EvenMoreAsserts.assertUnique(cid1, cid2, cid3, cid4, cid5, cid6, cid7, cid8);
244763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare the clock
244963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.install();
245063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
245163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // We check the timestamp in SQL, which doesn't know about the MockClock.  So we need to
245263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // use the  actual (roughly) time.
245363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
245463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long nowInMillis = System.currentTimeMillis();
2455d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long oneDayAgoInMillis = (nowInMillis - 24L * 60 * 60 * 1000);
2456d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long fourDaysAgoInMillis = (nowInMillis - 4L * 24 * 60 * 60 * 1000);
2457d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long eightDaysAgoInMillis = (nowInMillis - 8L * 24 * 60 * 60 * 1000);
2458d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long fifteenDaysAgoInMillis = (nowInMillis - 15L * 24 * 60 * 60 * 1000);
2459d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // All contacts older than 30 days will not be included in frequents
2460d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long thirtyOneDaysAgoInMillis = (nowInMillis - 31L * 24 * 60 * 60 * 1000);
246163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2462d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 30 days old
2463d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(thirtyOneDaysAgoInMillis);
246463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
246563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1, did2);
246663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1);
246763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2468d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 14 days old
2469d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(fifteenDaysAgoInMillis);
247063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
247163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3, did4);
247263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3);
247363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2474d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 7 days old
2475d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(eightDaysAgoInMillis);
247663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
247763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5, did6);
247863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5);
247963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
248063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Contact cid1 again, but it's an email, not a phone call.
248163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1e);
248263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2483d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 3 days old
2484d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(fourDaysAgoInMillis);
2485d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2486d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did7);
2487d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did7);
2488d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2489d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2490d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered less than 3 days old
2491d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(oneDayAgoInMillis);
2492d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2493d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did8);
2494d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2495d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(nowInMillis);
2496d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
249763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- The regular frequent, which is contact based.
2498d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Note because we contacted cid1 8 days ago, it's been contacted 3 times, so it comes
2499d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // before cid5 and cid6, which were contacted at the same time.
2500d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // cid2 will not show up because it was contacted more than 30 days ago
2501d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
250263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
2503d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid8),
2504d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid7),
250563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid1),
250663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid5),
250763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid6),
250863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid3),
2509d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid4));
251063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
251163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- phone only frequent, which is data based.
251263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note this is based on data, and only looks at phone numbers, so the order is different
251363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // now.
2514d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // did1, did2 will not show up because they were used to make calls more than 30 days ago.
251563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI.buildUpon()
251663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "1").build(),
2517d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did8),
2518d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did7),
251963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did5),
252063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did6),
252163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did3),
2522d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did4));
252363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
252463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
252545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
252645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
252745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
252845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
252945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
253045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
253145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
253245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
253345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
253445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
253545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
253645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
253745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
253845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
253945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
2540363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
2541363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
254245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
254345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
254445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
254545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
254645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
254745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
254845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
254945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
255045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
255145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
255245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
255345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
255445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
255545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
255645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
255745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
255845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
255945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
256045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
256145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
256245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2563363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2564363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
2565363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2566363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2567363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
2568363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2569363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2570363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
2571363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2572363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
2573363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
2574363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
2575363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
2576363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
2577363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2578363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2579363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2580363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2581363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2582363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
258345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
258445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
258580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    public void testQueryContactFrequentExcludingInvisible() {
258680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values1 = new ContentValues();
258780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email1 = "a@acme.com";
258880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
258980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
259080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values2 = new ContentValues();
259180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email2 = "b@acme.com";
259280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid2 = createContact(values2, "Sam", "Times", "18004664412",
259380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
259480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
259580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
259680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
259780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
259880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // First, we have two contacts in frequent.
259980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
260080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
260180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Contact 2 goes invisible.
260280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        markInvisible(cid2);
260380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
260480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Now we have only 1 frequent.
260580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values1});
2606216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2607216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    }
2608216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2609216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    public void testQueryDataUsageStat() {
2610216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        ContentValues values1 = new ContentValues();
2611216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final String email1 = "a@acme.com";
2612216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
2613216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
2614216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2615216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.install();
2616216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(100);
2617216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2618216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2619216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2620216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 1, 100);
2621216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2622216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(111);
2623216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2624216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2625216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 2, 111);
2626216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2627216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(123);
2628216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
2629216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2630216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 3, 123);
2631216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2632216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeLongText = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2633216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_LONG_TEXT).build();
2634216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2635216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeLongText, "a@acme.com", 2, 111);
2636216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2637216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(200);
2638216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2639216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2640216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2641216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2642216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 6, 200);
2643216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2644216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeCall = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2645216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_CALL).build();
2646216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2647216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeCall, "a@acme.com", 3, 200);
264880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    }
264980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
2650ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
26514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
26524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
26534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
26544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
2655aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
2656aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
26574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
26584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
26594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
2660aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
2661aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
26624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2663ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
26644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
26654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
26674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
26684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2670ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
26714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
26724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
26734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2676ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
26774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
26784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
26794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
26813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
268236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
268336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
268424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
268524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
268636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
268736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
268824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
268936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
269024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
269124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
269224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
269324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
269424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
269536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
269636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
269736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
269836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
269936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
270036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
270136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
270236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
270336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
270436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
270536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
270624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
270724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
270836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
270936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
271036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
271136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
271224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
271324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
271436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
271536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
271636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
271736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
271824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
271924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
272124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
272224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
272324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
272524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
272736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
272836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
272936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
273036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
273124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
273224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
273424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
273524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
273724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
273836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
273936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
274036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
274136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
274224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
274324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
274524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
274624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
274824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
274924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
275024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
275136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
275236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
275336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
275424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
275524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
275636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
275736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
275836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
275936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
276036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
276124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
276224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
276336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
276436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
276536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
276636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
276736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
276824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
276924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
277024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
277124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
277224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
277324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
277424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
277524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
277624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
277724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
277824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
277924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
278024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
278136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
278236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
278336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
278436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
278524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
278624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
278724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
278824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
278924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
279024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
279124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
279236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
279336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
279436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
279536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
279624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
279724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
279824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
279924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
280024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
280224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
280324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
280524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
280624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
280724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
280824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
280924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
281024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
281124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
281324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
281424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
281624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
281724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
281824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
281924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
282024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
282124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
282224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
28236ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
28246ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
28256ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
28266ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
28276ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
28288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Domo", "Arigato");
28296ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
28306ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
28316ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
28326ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
28336ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
28346ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
28356ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
28366ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
28376ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
28386ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
28396ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
28406ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
28416ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
28426ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
28436ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
28446ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
28455d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
284624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
284724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
284824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
284924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
285124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
285224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
285324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
28545d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
285524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
28565d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
28575d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
285824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
285924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
286124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
286224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
286324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
286524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
286624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
286724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
286924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
287024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
287224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
287324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
287424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
287624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
287724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
287924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
288024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
288124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
288224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
288424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
288524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
288624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
288724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
288924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
289024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
289124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
289224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
289324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
289424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
289524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
289624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
289724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
289824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
289924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
290024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
290124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
290224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
290324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
290424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
290524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
290624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
290724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
290824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
290924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
291024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
291124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
291224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
291324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
291424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
291524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
291624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
291724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
291824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
291924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
292024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
292124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
292224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
292324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
292424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
292524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
292624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
292724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
292824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
292924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
293024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
293124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
293224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
293324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
293424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
293524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
293624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
293724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
293824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
293924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
294024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
294124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
294224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
294324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
294424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
294524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
294624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
294724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
294824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
294924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
295024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
295124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
295224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
295324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
295424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
295524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
295624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
295724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
295824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
2959cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
2960cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
2961cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
2962cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
2963cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
2964cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
2965cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
2966cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2967cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
2968cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
2969cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2970a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
2971a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
2972a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
2973a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2974a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
2975a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
2976a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
29778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri profileUri = TestUtil.maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI,
29788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account)
2979a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
2980a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
2981a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
2982a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
2983a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2984a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
2985a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
2986a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
2987a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
298885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
298985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
299085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
299187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
299285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
299385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
299485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
299585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
299685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
299785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
299885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
299987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
300085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
300185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
300285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
300385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
30040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
300519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
300619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
300719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
300819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
30098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
301019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
301119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
301219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
301319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
301419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
301519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
301619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
301782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
3018aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
3019aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
302082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
3021aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
3022aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
302319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
302419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
302582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
302619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
3027a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
3028a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
302919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
303019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
303119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
303219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
303319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
303482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
30350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
303619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
303719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
303819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
3039a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
304019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
304119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
304219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
304319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
304419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
304582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
30460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
304719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
304819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
304919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
3050a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
305119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
305219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
305319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
305419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
305519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
305689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
305789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
305889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
305989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
306089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
30618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
30628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
306389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
306489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
306589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
306689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
306789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
306889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
30693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
30703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
30713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
30733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
30749d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
30753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
30763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
30773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
30783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
30793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
30803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
30813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
30823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
308394021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
30843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
30853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
30863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
30873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
30883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
30903cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
309173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
30923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
30933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
30943cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
3095f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
30968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3097f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3098f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3099f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
3100f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3101f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
3102f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3103f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3104f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
31058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3106f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3107f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3108f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3109f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
3110f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3111f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
3112f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3113f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3114f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
31158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3116f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3117f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3118f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
3119f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
3120f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
3121f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
3122f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
3123f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
3124f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
3125f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
3126f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
3127f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
3128f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
3129f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3130f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
31315f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
31325f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
31335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
31345f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31355f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
31365f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
31375f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
31385f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31395f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
31405f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
31415f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
31425f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
31435f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
31455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
31465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
31475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
31495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
31505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
31515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
31535f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
31545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
31555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31565f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
31575f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
31585f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31595f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
31605f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
31615f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
31625f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31635f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
31645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
31655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
31665f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31675f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
31685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
31695f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
31705f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
31715f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
31725f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
31735f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
31745f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31755f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
31765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
31775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
31785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
31805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
31815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
31825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
31845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
31855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
31865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
31885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
31895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
3190f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
3191f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
3192f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
3193f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
3194f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
3195f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
3196f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3197f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
3198f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
31998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId0 = RawContactUtil.createRawContactWithName(mResolver, "firstName0",
32008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName0");
3201f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
32028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "firstName1",
32038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName1");
3204f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
3205f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
3206f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
32078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "firstName2",
32088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName2");
3209f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
3210f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
3211f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
3212f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3213f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
3214f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
3215f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
3216f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
3217f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
3218f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
3219f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
3220f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
3221f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3222f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
3223f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
3224f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
3225f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
3226f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
3227f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
3228f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
3229f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
3230f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3231f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
3232f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
3233f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
3234f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
3235f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
3236f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
3237f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
3238f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
3239f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3240f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3241f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3242f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
3243f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
3244f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
3245f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
3246f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3247f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3248f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3249f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
32508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "firstName3",
32518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName3");
3252f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
3253f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
3254f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
3255f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
3256f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3257f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3258f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3259f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
326018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
326118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
326218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
326318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
326418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
326518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
326618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
326718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
326818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
326918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
327018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
327118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3272f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
3273f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3274f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
3275f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
3276f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
327718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
327818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
327918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
328018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
328118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
328218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3283f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
3284f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
3285f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
3286f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
3287f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
3288f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
3289f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
3290f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
329118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
329218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
329318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
329418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
329518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
329618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3297f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
329823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
329923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
330023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
330123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
330223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
330323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
330423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
330523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
330623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
330723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
330823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
330923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
3310f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3311f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
331289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
331389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
331489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
3315f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
331689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
331789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
3318f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
33198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
33208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
3321f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
3322f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
3323f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
3324f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
3325f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
332689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
332789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
3328f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
332989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
3330f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
333189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
3332f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
3333f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
3334f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
3335f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
3336f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
3337f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
3338f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
3339f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
3340f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
3341f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
3342f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
33430e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
33440e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
33450e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
33460e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
33470e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
33480e21a867a572679d64d79041eb574d13665178d4Dave Santoro
33490e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
33500e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
33510e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
33520e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
33530e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
335489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
335589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
33564097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
33578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
33584097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
33594097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
33608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
33614097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
336217a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
33634097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
33644097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
336567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
33668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
336767c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
336867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
336967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
337067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
33718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
337217a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
337367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
337467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
33754097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
33768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
33774097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
33784097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
33794097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
33808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
33814097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33825ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
33834097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
33844097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
3386a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.ENGLISH);
33878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, null);
33885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
33905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
33915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
33925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
33935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
33945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
33958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
33965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
339955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
340055e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
34015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
34025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
34035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3404a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
34055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3406a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
34095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
34105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
341355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
341455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
34155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
34165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
34175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3418a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
34195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3420a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
3431a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
34325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
34335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
3434a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
34355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
34375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
3439a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        // "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B"
34405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
34418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
34425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
34465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
34475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
34485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3449a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3450a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3451a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3452a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
34555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
34565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
34605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
34615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
34625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3463a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3464a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3465a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3466a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34760f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    public void testJapaneseNameContactInEnglishLocale() {
34770f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // Need Japanese locale data for transliteration
34780f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        if (!hasJapaneseCollator()) {
34790f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            return;
34800f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        }
34810f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContactLocaleUtils.setLocale(Locale.US);
3482ef5fa9a68690d19e2a9c9748d63e2cabb5075813Jay Shrauner        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
34830f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34840f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContentValues values = new ContentValues();
34850f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
34860f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
34879aec6b8422f8d153a91a241f1b10d6e48d338bb8Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
34880f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34890f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
34900f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // en_US should behave same as ja_JP (match on Hiragana and Romaji
34910f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // but not Pinyin)
34920f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
34930f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
34940f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
34950f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    }
34960f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
3498a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3499a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3500a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3501a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
35028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
35035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
35055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
35065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
35078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
35085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
35115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
35125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
35135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
35145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
35155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
35165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3517a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3518a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
35195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
35215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
35225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
35255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
35265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
35275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
35285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
35295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
35305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3531a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3532a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
35335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
35355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
35365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
35375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
35395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
35400f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
35410f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
35420f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // ja_JP should match on Hiragana and Romaji but not Pinyin
35430f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
35440f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
35450f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
35465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
354825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
35498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
355025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
355125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
35528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
355325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
355425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
35550c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
35560c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
355725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
355825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
355925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
35608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Potato", "Head");
356125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
356225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
356381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
356425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
356525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
356601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
35678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
356801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3569a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
357001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
357101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
357201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
357301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
357401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
357501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
357601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
357701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
357801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
357901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
358001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
358101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
358201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3583a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
3584a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3585a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
35865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
358701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
358801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3589a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
3590a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
3591a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
3592a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
3593a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
3594a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3595a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
3596a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
3597a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
35988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
35995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
36005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
36015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
36038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
36045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
36055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
36065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
36085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
36105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
36125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
36135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
36145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
36165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
36185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
36195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
36225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
36235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
36245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
36255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
3626a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "M");
3627a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "M");
36285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
36295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
36305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
3632a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3633a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3634a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3635a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
36368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
36375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
36385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
36395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
36415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
36435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
36455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
36465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
36475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
36505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
36515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
36525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
36535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
3654a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u305F");
3655a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u305F");
36565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
36575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
36585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
3660a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
36610b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
36620b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
3663a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
36640b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
36658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
36665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
36675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
36685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
36705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
36725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
36745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
36755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
36785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
36795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3680a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u4E2D\u56FD\u7535\u4FE1");
3681a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "Z");
3682a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u4E2D\u56FD\u7535\u4FE1");
3683a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "Z");
36845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
368501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
368601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
368731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
36888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
368931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
369031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
369131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
369231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
369331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
369431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
369531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
369631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
369731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
369831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
369931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
370031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
370131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
370231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
370331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
370431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
370531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
370631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
370731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
370831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
370931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
371031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
371131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
371231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
371331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
371431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
371531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
371631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
371731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
371831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
371931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
372031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
372131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
372231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
372331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
372431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
372531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
372631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
372731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
372831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
372931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
373031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
373131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
373231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
373331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
373431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
3735a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
37360f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
37370f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertEquals(0, getCount(filterUri, null, null));
3738a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
3739a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
3740916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
37418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3742916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3743916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3744916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
3745916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
3746916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3747916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3748916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3749916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
37509c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
3751916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
3752916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3753916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
3754916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
3755916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3756916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3757916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
3758916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
3759916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3760916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3761916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
3762916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3763916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37646f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3765916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3766916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3767916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37686fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "acmecorp");
37696fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(filterUri, values);
3770916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3771916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3772916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
37738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
3774916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3775916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3776916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
3778916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3779916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37806f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3781916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3782916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3783916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37846fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "acme@corp.com");
3785916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3786916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3787916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3788fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
3789fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
3790fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
3791fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
3792fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
3793fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
3794fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
3795fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
3796fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
3797fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
3798fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
3799fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
3800fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
38013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
38028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
38053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
38073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
38083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
38103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
38113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
38123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
38153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
38173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
38193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
38213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
38233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
38253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
38263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
38273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38296f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
38306f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
38316f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
38326f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
38336f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
38346f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
38356f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
38366f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
38376f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
38386fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    public ContentValues createSnippetContentValues(long contactId, String snippet) {
38396fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        final ContentValues values = new ContentValues();
38406fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.clear();
38416fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(Contacts._ID, contactId);
38426fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, snippet);
38436fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        return values;
38446fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    }
38456fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng
3846916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
38478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3848916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3849916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3850916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3851916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
3852916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
38536f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
3854916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3855916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3856916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
38576fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "Incredible");
3858916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3859916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3860916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
38613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
38628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
38653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38676fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
38683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38696fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
38706fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("john", true), snippet);
38713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
38748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38753716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
38773716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38796fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
38803716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38816fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
38823716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38833716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
38858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38873716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
38883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
38893716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
38903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
38913716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
38923716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
38933716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38946fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "aperturepresident");
38953716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38966fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("aperture", true), snippet);
38973716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38983716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38993716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
39008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
39013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
39023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
39033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
39043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
39056fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "860-555-1234");
39063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
39076fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("860", true), snippet);
39083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
39093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
39103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
39118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
39123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
39133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
39143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
39153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
39166fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId,
39176fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng                "Cave Johnson is president of Aperture Science");
39183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
39196fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
39203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
39213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
3922dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
39238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
39248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, "Slinky", "Dog");
3925dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3926dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3927dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3928dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3929dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
3930dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3931dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
3932dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
3933dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3934dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3935dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
3936dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3937dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
3938dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3939dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3940dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
3941dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3942dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
3943dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3944dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3945dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
3946dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
3947dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3948d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
3949d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
3950d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
3951d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3952d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
3953d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
3954d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
3955d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
3956d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
3957d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3958d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
3959d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
3960d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
3961d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3962d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
3963d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
3964d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
3965d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
39668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3967d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3968d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3969d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3970d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3971d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3972d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
3973d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3974d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3975d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3976d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
39778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3978d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3979d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3980d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
3981d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
398281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
39838c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
39848c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
39858c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
39868c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
3987d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3988d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3989d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
39908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "a", "b");
3991d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3992d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3993d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "c", "d");
3995d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3996d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
3997d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3998d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39990c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
40000c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4001d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4002d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
4003d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
4004d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4005d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4006d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
40078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "e", "f");
4008d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
4009d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
4010d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
40118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "g", "h");
4012d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
4013d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
4014d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4015d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
40160c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
40170c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4018d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4019d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
40200c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
4021d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4022d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4023d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
40248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "i", "j");
4025d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
4026d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
4027d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
40288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "k", "l");
4029d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
4030d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
4031d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4032d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
40330c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
40340c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4035d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4036d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
40370c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
40380c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4039d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
40403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
4041d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
4042d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4043d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
404482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
40458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
40470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
40480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
40500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40510a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
40520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
40530a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
40540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
40550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40560a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
40570a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
40580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
40590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
40600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
40620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
40640a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40650a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
40660a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
40670a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40680a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40690a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
40710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
40720a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
40730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
40740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
40750a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40760a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40770a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40780a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40790a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
40810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
40820a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
40830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
40840a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
40850a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
40860a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40880a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
40900a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
40910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
40920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
40930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
40940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
40960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
40988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
41000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
41010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
41020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
41030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
41040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
41050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
41060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
41070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
41080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
41090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
41100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
41110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
41120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
41130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
41140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
41150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
41160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
41170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
41180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
41198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
41204dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
41214dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
412282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
41234dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
41244dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
4125aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4126aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
41274dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
41284dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
4129aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
4130d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
41314dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
41324dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
4133aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
4134aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
41354dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
41364dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
4137aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
4138aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
41394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
414082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
414182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
41420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
414382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
41444dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
414582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
41464dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
414782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
41484dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
414982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
41504dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
41514dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
4152bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4153bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4154bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4155bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4156bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
415782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
41580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4159bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4160bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
4161bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
416282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
41638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4164bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4165bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4166bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4167bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4168bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4169bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
417082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
417182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
4172bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4173bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4174aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
4175aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4176aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
4177aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
417882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
4179aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4180aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
418182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4182bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
418382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
418482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4185bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4186bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
41879705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
41889705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
41899705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
41909705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
41919705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
41929705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
41939705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
41949705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41959705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41969705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41979705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
41989705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41999705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
42009705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
42019705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
42029705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
42039705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
42049705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
42059705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
42069705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
42079705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
42089705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
42099705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
42109705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
42119705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
42129705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
42139705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
42149705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
42159705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
42169705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
42179705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
42189705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
42199705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
42209705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
42219705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
42229705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
42239705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
42249705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
42259705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
42269705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
42279705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
42289705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
42299705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
42309705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
423182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
42329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
423382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4234a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4235a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
4236a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4237093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
42388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4239093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4240093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4241093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4242093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4243093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4244093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
4245093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
4246093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4247093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
4248093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4249093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4250093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
4251093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4252093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4253093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4254093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4255093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
4256093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
4257093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
4258093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4259093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4260093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4261093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4262093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4263093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
4264093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
426582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
42668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4267a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4268a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
4269a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4270a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4271a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4272aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
42735d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4274aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
42755d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4276aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
42775d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4278a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4279a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
4280a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
428182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
428282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4283bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
42844dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42854dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
428682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
428782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
42884dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
428982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
429082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
4291a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
429282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
42934dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
42944dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42954dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
42963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
42973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
42998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
43003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
43023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
43033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
43043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
43053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
43063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
43073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
43108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
43123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
43143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
43153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
43163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
43173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
43183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
43193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
43228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
43243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
43253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
43273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
43283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
43293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
43303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
43313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
43323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
43358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
43373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
43383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
43403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
43413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
43423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
43433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
43443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
43453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
43463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
43473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
43508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
43533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
43543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
43578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
43603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
43643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
43683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
43723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
43758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
43873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
43883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
43913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
43923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
43953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
43978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
44003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
44013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
44033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
44046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
44063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
44073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
44093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
44103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
44113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
44148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
44173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
44183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
44193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
44203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
44223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
44233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
44243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
44253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
44273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
44283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
44296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
44323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
44336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
44346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
44353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
44366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
44393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
44403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
44413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
44423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
44458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
44483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
44493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
44503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
44513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
44533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
44543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
44553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
44563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
44583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
44593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
44603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
44616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
44643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
44656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
44666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
44673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
44683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
44696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
44723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
44753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
44773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
44783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
44803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
44833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
44853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
44863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
44893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
44913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
44923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
44943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
44963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
44983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
44993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
45013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
45033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
45043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
45053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
45063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
45073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
45118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
45143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
45153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
45163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
45183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
45218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
45243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
45263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
45283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
45293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
45303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
45313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
45333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
45353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
45373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
45383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
45393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
45413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
45423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
45443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
45453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
45463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
45473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
45483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
45493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
45523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
45558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
45583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
45603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
45613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
45633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
45653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
45663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
45693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
45703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
45713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
45733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
45763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
45788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
45803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
45813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
45833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
45843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
45853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
45873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
45883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
45903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
45913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
45923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
45933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
45943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
45963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
45983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
45993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
46003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
46013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
46023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
46033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
46043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
46053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
46063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
46073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
46083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
46093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
46113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
46136802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
46143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
46153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
46163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
46176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
46186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
46196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
46206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
462187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                EvenMoreAsserts.assertImageRawData(getContext(),
4622c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                        expectedPhotoBytes, mResolver.openInputStream(Uri.parse(photoUri)));
46236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
46243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
46253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
46263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
46273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
46303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
46328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
46373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
46383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
46393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
46423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
46458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
46503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
46513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
46523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
46553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
46583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
46608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
46713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
46723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
46733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
46753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
46763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
46776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
46783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
46796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
46806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
46816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
468287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4683c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
46846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
46853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
46888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
46976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
47003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
47013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
47033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
47046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
47053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
47066802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47076802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
47086802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
470987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4710c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
47116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
47123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
47153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
47178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
47193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
47203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
47213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
47233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
47243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
47253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
47273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
47283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
47293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
47313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
47323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
47333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
47343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
47378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
47393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
47403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
47423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
47433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
47443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
47463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
47473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
47483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
47503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
47513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
47523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
47533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
47563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
47588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
47623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
47633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
47643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
47653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
47663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
47683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
47693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
47713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
47723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
47733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
47743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
47753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
47763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
47773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
47783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
47793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
47828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
47863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
47873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
47886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
47893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
47903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
47913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
47933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
47943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
47963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
479882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
47998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
480082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
480182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
480282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
480382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
480482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
480582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
480682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
480782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
480882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
480982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
481082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
481182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
481282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
481382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
48143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
48153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
48163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
48173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
48183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
48216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
48226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
48246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
48266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
48276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
48286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
48296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
48306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
48316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
48326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
48346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48354747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
4836d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
4837d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
4838d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
4839d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
4840d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
4841d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4842d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
4843d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4844d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
4845d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
4846d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
4847d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
4848d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
4849d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
4850d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4851d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
4852d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
4853d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
4854d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4855d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
4856d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48574747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
48586802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
48656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
48676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
48686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
48696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
48706802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
48716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
48726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
48736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
48756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
48766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
48776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
48796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48804747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
48816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48836802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
488736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
48888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
488936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
489036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
489136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
489236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
489336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
489436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
489536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
489636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
489736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
489836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
489936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
490036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
490136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
490236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
490336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
490436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
490536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
490636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
490736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
490836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
490936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
491036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
491136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
491236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
491336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
491436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
491536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
491636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
491736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
491836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
491936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
492036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
492136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
492236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
492336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
492436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
492536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
492636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
492736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
492836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
492936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
493036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
493136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
493236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
493336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
493436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
493536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
493636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
493736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
493836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
493936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
49408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
494136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
494236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
494336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
494436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
494536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
494636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
494736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
494836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
494936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
495036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
495136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
495236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
495336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
495436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
495536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
495636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
495736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
495836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
495936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
496036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
496136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
496236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
496336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
49648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
496536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
496636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
496736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
496836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
496936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
497036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
497136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
497236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
497336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
497436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
497536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
497636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
497736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
497836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
497936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
498036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
498136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
498236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
498336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
498536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
498636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
498736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
498836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
498936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
499036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
499136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
499236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
49938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
499436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
499536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
499636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
499736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
499836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
499936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
500036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
500136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
500236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
500336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
500436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
500536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
500636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
500736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
500836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
500936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
501036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
501136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
501236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
501336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
501436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
501536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
501636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
501736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
501836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
501936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
502036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
502136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
502236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
502336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
502436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
502536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
502636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
502736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
502836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
502936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
50308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
503136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
503236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
503336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
503436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
503536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
503636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
503736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
503836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
503936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
504036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
504136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
504236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
504336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
504436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
504536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
504636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
50473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
50483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
50493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
50503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
50513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
50523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
50533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
50563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
50573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
50586802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
50596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
50603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
50613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
506382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
5064bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
5065bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
5066bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
50678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
50684dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
5069bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5070aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
5071aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5072aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
5073aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5074aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
5075aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5076bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5077af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
507882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
50794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
5080bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5081bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
508282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
508382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
50840265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
5085bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
5086bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5087d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
5088d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
5089d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
5090d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
5091d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
5092d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
5093d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5094d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5095d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5096d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
5097d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
50988c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
50998c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
51008c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
51018c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
51028c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
51038c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
51048c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
51058c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
51068c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
51078c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
51088c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
51098c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
51108c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
5111d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
5112d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5113d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
5114d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
5115d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
5116d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
5117d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
5118d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
5119d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
5120d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
5121d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
5122d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
5123d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
5124d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5125d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
5126d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
51279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51280be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
51298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
51300be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
51310be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51320be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
51330be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
51340be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51350be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
51360be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
51370be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51380be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
51390be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
51400be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51410be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
51420be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
51430be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51440be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
51450be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
51460be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51470be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
51480be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
51490be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
51500be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51510be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
51520be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
51530be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
51540be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
51550be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51560db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
51570db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
51580db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
51590db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
51600db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
51610db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
51620db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
51630db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51640db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
51650db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
51660db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51670db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
51680db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
51690db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51700db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51710db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51720db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51730db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
51740db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
51750db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51760db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
51770db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
51780db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51790db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51800db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
51810db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51820db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
51830db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
51840db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
51850db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
51860db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
51870db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
5188a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
51899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
51909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
51919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
51939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
51949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID, "c0");
51963cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
51973cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
51983cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
51999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c1 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
52018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c1");
52029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
52039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
52049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
52059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
52069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c2 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
52088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c2");
52099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
52109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
52119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
52129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c3 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
52148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c3");
52159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
52169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
52179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
52189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
521962318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
52208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount),
52218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                null, RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
52229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
52239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
52249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
52256cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
52269261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
52279261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
52289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
52299261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
52309261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
52319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
52329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
52339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
52349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
52359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
52369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
52379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
52389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
52399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
52409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
52419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
52429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
52446cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
52459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
52469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
52479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
52489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
52499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
52509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
52519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
52529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
52539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
52549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
52559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
52569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
52579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
52596cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
52609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
52619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
52629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
52639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
52649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
52659261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
52669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
52679261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
52689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
52699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
52709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
52719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
52729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
52743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
52759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
527620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
527720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
52788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
527920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
528020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
52815ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
528220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
528320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
528420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
528520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
528620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
528720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
528820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
528920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
529020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
529120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
529220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
529320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
529420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
529520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
529620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
529720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
529820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
529920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
530020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
530120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
530220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
530381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
530420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
530520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
530620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
530720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
530820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
530920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
531020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
531120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
531220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
531320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
531420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
531520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
531620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
531720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
531820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
531920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
532020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
532120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
532220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
532320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
53245ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
532520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
532681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
532770b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
532820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
532920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
53305ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
533120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
533220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
53335ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
533433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
533581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
533633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
533720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
533889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
533989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
534089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
53418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
53428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
534389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
53448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
53458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
534689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
534789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
534889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
534989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
535089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
535189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
535289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
535389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
535489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
535589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
535689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
5357373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
53588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
53595ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
536033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53614dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
536282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5363aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5364aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5365a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
5366a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
536733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
536833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
536982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53704dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
537133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
537233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
537333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53745870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
537581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
537633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
5377e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
537833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
537933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
538033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
538133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
538282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53834dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
5384a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
538581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
5386a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
5387a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5388a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
53898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
53908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
539147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
539247fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
5393a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5394a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5395a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5396a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
5397e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
5398a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
5399a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
5400a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
540120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
54021fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
54035f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
54048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5405e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
5406e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5407e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
540882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5409aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5410aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5411e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
5412e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
541382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
5414e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
5415e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5416e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
5417e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
5418e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5419e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
5420e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
5421e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
54225f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
54235f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
5424e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54255870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
5426e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5427e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
5428e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
5429e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5430e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
5431e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
5432e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
54335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
54345f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
54355f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
54365f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
54375f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
54385f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
54395f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
54408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
54415f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
54425f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
54435f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
54445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
54455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
54465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
54475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
54485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
54495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
54505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
54515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
54525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
54535f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
54545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
54555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
5456e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54575870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
5458e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
5459e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54609ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
54619ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
54629ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
54639ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
54649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
54659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
54668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2);
54699ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54709ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
54718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1);
54749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
54769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
54779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
54789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54799ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54809ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
54819ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
54829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
54839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54849ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54869ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
54969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
54979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
54989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
54999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
55009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
55019ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
55039ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
55049ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
55059ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
55079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
55089ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
55099ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
55109ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
55119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
55129ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55139ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
55148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1 = new Account[] {TestUtil.ACCOUNT_1};
55158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2 = new Account[] {TestUtil.ACCOUNT_2};
55168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1_2 = new Account[] {TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2};
55178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2_1 = new Account[] {TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1};
55189ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55199ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
55209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
55229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
55239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
55249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
55269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55279ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
55289ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
55299ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
55309ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
55319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
55329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
55339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
55349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
55369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
55389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
55399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
55409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
55429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
55449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
55459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
55469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
55489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
55509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
55519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
55529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
55539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
55549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
55559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
55569ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
5557627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
555870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
555970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
55608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
556170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
5562627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
5563743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
556470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
556570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5566bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
5567743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
5568743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
5569dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
5570dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
557170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
55728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
5573743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
55748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
5575743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
5576743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
5577743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5578aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5579aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5580743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
5581bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
5582743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
5583627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
558482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
558570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
558670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
558770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
558833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
558933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
559033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5591bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
559233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
559333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
55948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
55958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                readOnlyAccount);
559633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
55978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "john", "doe",
55988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                mAccount);
559933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
560033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
560133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
560233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
560333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
560433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
560533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
560633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
560733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
560833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
560933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
561033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
561133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
561233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
561333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
561433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
561533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5616bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
561733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
561833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
561933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
562033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
562133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
562233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
562333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
562433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
562533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
562633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
562733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
562833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
562933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
563033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5631c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
5632c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
5633c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
5634c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5635c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
5636c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
5637c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5638c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
56398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long doomedRawContactId = RawContactUtil.createRawContactWithName(mResolver, doomedAccount);
5640c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
5641c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
5642c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
5643c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
5644c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
5645c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5646c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
56478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long safeRawContactId = RawContactUtil.createRawContactWithName(mResolver, safeAccount);
5648c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
5649c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
5650c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
5651c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
5652c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
5653c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
5654c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5655c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
5656c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
5657c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
5658c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5659c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
5660c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
5661c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
5662c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
5663c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
5664c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
5665c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5666c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
5667c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
5668c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
5669c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
5670c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
5671c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
5672c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5673cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
56748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
56768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
5678cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5679cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5680cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5681cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
5682cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5683cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
5684cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5685cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
5686cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5687cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
5688cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
568973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
56908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
569173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
569273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
56938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
569473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
5695e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
569673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
569773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
569873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
569973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
57005870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
570173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
570281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
57031fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57041fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
570561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
57068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5707d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
570873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
57091fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
57101fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
57111fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
57121fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
57131fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
571461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
5715c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
571661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
57171fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
57181fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57191fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
57201fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
572181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
57221fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
572361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
572461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
572581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
57261fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
57271fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
572861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
57291fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
573061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
573161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
573261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
57331fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
573481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
57351fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
57361fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
573761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
57381fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
573961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
57401fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
574181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
57421fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
57431fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
574461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
57451fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
574661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
57478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
574861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
574961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
575061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
575161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
57521fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
575361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
57541fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57551fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
57561fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
57571fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
57581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57591fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
576161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
57628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
57631fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
576461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
57651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
576661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
576761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
576861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
576961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
57705870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
577161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
577281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
577361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
577461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
57751fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
57779fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
57789fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57799fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57809fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57819fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
57829fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57839fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57849fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57859fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57869fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57879fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
57889fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
57899fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
57909fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57919fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
57929fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57939fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57949fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57959fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57969fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57979fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57989fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57999fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
58009fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
58019fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
58029fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
580360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
580460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
580560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
580660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
580760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
580860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
580960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
581060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
581160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
581260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
581360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
581460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
581560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
581660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
581760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
581860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
581960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
582060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
582160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
582260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
582360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
582460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
582560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
582660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
582760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
582860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
5829074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
5830074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
5831074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
5832074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
58338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
5834f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5835f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5836f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
5837f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
5838f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5839074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
58403d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
58413d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
5842f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
5843074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
5844074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
5845bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
58468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5847bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
5848bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5849bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
5850bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
5851bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5852bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
5853bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5854bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
5855bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
5856bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5857bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
5858bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5859bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
5860bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
5861bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
5862bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
5863bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
5864bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5865bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
586687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5867c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithId));
586887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5869c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
5870bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
5871bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5872ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
58738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5874f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5875f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5876f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
5877f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
5878f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
5879e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
588087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Check the thumbnail.
588187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
5882f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
588387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki
588487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Then check the display photo.  Note because we only inserted a small photo, but not a
588587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // display photo, this returns the thumbnail image itself, which was compressed at
588687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // the thumnail compression rate, which is why we compare to
588787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL) rather than loadTestPhoto(PhotoSize.DISPLAY_PHOTO)
588887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // here.
588987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // (In other words, loadTestPhoto(PhotoSize.DISPLAY_PHOTO) returns the same photo as
589087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL), except it's compressed at a lower compression rate.)
589187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
589287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                mResolver.openInputStream(photoUri));
5893ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
5894ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
5895732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
58968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
5897f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
5898732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
5899732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
59008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
5901f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
5902732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
5903732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5904732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5905732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5906732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5907732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5908732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5909f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5910f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5911f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
5912f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
5913f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5914732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5915f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
5916732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5917732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
5918732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5919732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5920732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
5921732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
5922732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
5923732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5924732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5925732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5926732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5927732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5928732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
5929732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5930732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
5931732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5932732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
5933732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
59348e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
59358e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
59368e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
59378e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
59388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
59398e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59408e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
59418e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
59428e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59438e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
59448e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
59458e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59468e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
59478e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
59488e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
59498e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5950155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
59518e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59528e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
59538e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
59548e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
595581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
59568e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5957f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
59588e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
59598e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
59608e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59614e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
59627d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
59637d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
59647d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
59657d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
59667d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59677d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
59687d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
59697d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59707d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
59717d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59727d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
59737d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
59747d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
59757d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
59767d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59777d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59787d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59797d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
59807d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59817d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
59827d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
59837d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59847d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
59857d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59867d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59877d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59887d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
59894e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
59907d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
59914e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
5992f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
59930265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
59947d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
59957d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
5996f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
59978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5998f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5999f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6000f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
6001f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
6002f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
600387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6004f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6005f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6006f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6007f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6008f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
60098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6010f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6011f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
6012f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6013f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
6014f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
6015f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
601687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6017f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6018f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6019f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6020f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6021f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
60228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6023f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6024f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
6025f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6026f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
6027f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
6028f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
6029f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
603087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6031f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6032f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6033f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6034f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6035f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
60368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6037f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6038f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
6039f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6040f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
604187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6042f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6043f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6044f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6045f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6046f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
60478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6048f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6049f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6050f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6051f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
6052f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6053f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6054f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
605587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6056f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6057f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6058f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6059f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6060f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
60618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6062f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6063f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6064f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
6065f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6066f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6067f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
6068f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6069f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6070f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6071f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6072f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
6073f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6074f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6075f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6076f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
6077f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6078f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
6079f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
6080f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6081f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6082f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6083f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
60848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6085f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6086f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6087f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
6088f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
6089f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
6090f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6091f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6092f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6093f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6094f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
6095f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6096f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6097f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6098f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6099f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6100f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
6101f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
6102f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6103f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
6104f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6105f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
610787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6108f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6109f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6110f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6111f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6112c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
61138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6114f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6115f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6116f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6117c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
6118c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
6119f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6120f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6121c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6122f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6123f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6124c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6125f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6126f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
6127c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
6128c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
6129c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
6130c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
6131c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
6132c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6133c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
6134c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
6135c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6136f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
6137f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6138f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6139f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6140f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
6141c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
6142f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6143f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
614487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6145f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6146f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
614787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6148f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6149f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
6150f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6151f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6152c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
61538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
6157f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
6158f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
6159f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6160f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6161f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6162f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
6163f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6164f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6165f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6166f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6167f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6168c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6169c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6170c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
6171c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
6172f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6173f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
6174f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
6175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
6177f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
6179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
6180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
618287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6184f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
618587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6186f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6187f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
6188f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6190f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6191c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
6192c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
6193c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
6194c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
6195c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
6196c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
6197c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
6198c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
6199c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
6200c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
6201c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
6202c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
6203c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
6204c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
6205c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
6206c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
6207c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
6208c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6209f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
6210f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6211f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
6212f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
6213f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
6214f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6215f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6216f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
6217f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6218c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
6219f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6220f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
62248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
6225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
6226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
6227f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
6228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
6229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
62318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
6232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
6233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
6234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
6235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6238f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
6239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
6241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
6243f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
6244f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
6245f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
6246f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6247f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6248f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6249f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
6250f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
62518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver);
6252f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
6253f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
6254f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
6255f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6256f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
6257f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
6258f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
6259f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
6260f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
6261f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6262c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
6263c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
6264c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
62658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId4 = RawContactUtil.createRawContactWithName(mResolver, socialAccount);
6266c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
6267c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
6268c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6269c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6270c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6271c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6272c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6273c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
6274c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6275f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
6276f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
6277f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
6278f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6279f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
6280f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6281f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6282f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
6283f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6284f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
6285f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
6286f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
6287f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6288f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6289f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
6290f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
6291f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
6292f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6293f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
6294f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6295f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
6296f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
6297f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
6298f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6299f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6300f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
6301f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
6302c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6303c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
6304c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6305c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6306c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6307c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
6308f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6309f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6310d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
6311d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6312d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
6313d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6314d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6315ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6316d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6317d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6318d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
6319d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
6320d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
6321d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
6322d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
6323d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
6324d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
6325d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
6326d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
6327d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
6328d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6329d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
6330d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6331d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
6332d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
6333d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
6334d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
6335d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6336d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6337d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6338d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6339d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6340d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6341d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
6342d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
6343d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
6344d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6345d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
6346ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6347d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6348d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6349d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
6350d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6351d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
6352d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6353d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6354d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6355d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
6356d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6357d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
6358d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
6359d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
6360d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
6361d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6362d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
6363d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6364f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
63658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6366f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6367f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6368f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6369f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
6370f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6371f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
6372f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
6373f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6374f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
6375f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
6376f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
6377f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
6378f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6379f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
6380f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
6381f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
6382f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
6383f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
6384f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6385f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6386f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
638787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6388c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6389f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6390f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6391f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
63924e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
63938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
63944e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
63958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
63964e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
639747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
639847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
63994e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64004e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
64014e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
64024e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
64034e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64044e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
64054e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
64064e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64074e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
64084e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64094e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
64104e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
64114e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
64124e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64134e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
64144e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
64154e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64164e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
64174e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
64184e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
64194e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64204e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
64214e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
64224e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64234e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
64244e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
64254e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
64264e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
64274e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
64286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
64298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
64306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
64316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
64326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
64346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
64356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
64366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
64446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
64456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
64476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
64506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
64516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
64556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
64566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
64596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
64606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
64686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
64696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
64726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
64736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
64856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
64886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
64896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
64976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
65006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
65016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
65046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
65056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
65066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
65076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
65096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
65106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
65116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
65126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
65136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
65166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
65176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
65186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
65196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
65206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
65216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
65226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
65236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
65266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
65276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
65286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
65296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
65308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
65316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
65326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
65346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
65356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
65366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
65376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
65406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
65416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
65436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
65446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
65456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
65466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
65486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
65496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
65506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
65516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
65536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
65546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
65556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
65566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
65576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
65586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
65616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
65626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
65636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
65646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
65656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
65666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
65696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
65706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
65736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
65746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
65776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
65786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
65816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
65826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
6584a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    public void testContactSortOrder() {
6585a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + ", "
6586a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY,
6587a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY));
6588a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + ", "
6589a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_ALTERNATIVE,
6590a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE));
6591a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + " DESC, "
6592a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY + " DESC",
6593a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY + " DESC"));
6594a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        String suffix = " COLLATE LOCALIZED DESC";
6595a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + suffix
6596a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + ", " + Contacts.SORT_KEY_ALTERNATIVE + suffix,
6597a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE
6598a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                                                             + suffix));
6599a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
6600a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
6601ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
6602ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
6603ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
6604ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
66058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContact(mResolver);
66068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
66078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "The Abominable", "Snowman");
66088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mike", "Wazowski");
66098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "randall", "boggs");
66108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Boo", null);
66118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mary", null);
66128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Roz", null);
6613ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6614ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
6615ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6616a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                null, null, Contacts.SORT_KEY_PRIMARY);
6617ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
661835997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "", "B", "J", "M", "R", "T");
6619ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
6620ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6621ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6622ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
6623ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6624ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
6625ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
662635997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", "");
6627ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
6628ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6629ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6630ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
66311f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    public void testContactCountsWithGermanNames() {
66321f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        if (!hasGermanCollator()) {
66331f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            return;
66341f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
66351f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        ContactLocaleUtils.setLocale(Locale.GERMANY);
66361f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
66371f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Uri uri = Contacts.CONTENT_URI.buildUpon()
66381f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
66391f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
66408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Josef", "Sacher");
66418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Franz", "Schiller");
66428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Eckart", "Steiff");
66438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Klaus", "Seiler");
66448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Lars", "Sultan");
66458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Heidi", "Rilke");
66468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Suse", "Thomas");
66471f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
66481f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Cursor cursor = mResolver.query(uri,
66491f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                new String[]{Contacts.DISPLAY_NAME},
66501f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                null, null, Contacts.SORT_KEY_ALTERNATIVE);
66511f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
66521f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterValues(cursor, "R", "S", "Sch", "St", "T");
66531f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterCounts(cursor,   1,   3,     1,    1,   1);
66541f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        cursor.close();
66551f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
66561f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
6657ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
6658ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
6659ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
6660ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6661ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6662ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6663ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
6664ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
6665ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
6666ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6667ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6668ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6669f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
6670f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
6671f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
6672f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
6673f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
6674f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
6675f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
6676f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
6677f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
6678f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
6679f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
6680f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
6681f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6682f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6683f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
6684f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
6685f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
6686f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
6687f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6688f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6689f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
6690f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
6691f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
6692f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
6693f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
6694f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
6695f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
6696f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
6697f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
66985fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
66995fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
67005fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
67015fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
67025fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
67035fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
67045fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
67055fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
67065fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
67075fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
67085fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
67095fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
67105fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
6711f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6712f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6713e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
6714e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
6715e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
6716e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
6717e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6718e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
6719e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
6720e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6721e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6722e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6723e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6724e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6725e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
6726e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
6727e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
6728e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
6729e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6730e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
6731e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
6732e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
6733e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
67348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri insertUri = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI,
67358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                blue);
6736e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6737e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
6738e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
6739e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6740e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6741e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6742e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6743e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
67443826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
67453826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67463826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67473826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67483826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
67498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
67503826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
67513826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
67523826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
67533826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67543826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67553826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67563826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
67573826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        mActor.setAccounts(new Account[]{TestUtil.ACCOUNT_1});
67598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{TestUtil.ACCOUNT_1});
67603826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
6761bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
67623826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
67633826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67643826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67653826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67663826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
676709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
676809c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
676909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
677009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
67713826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
677209c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
677309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
677409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
6775b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
6776743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
6777b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
6778b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
6779b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
6780b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
6781b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
6782b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
6783b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
6784b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
6785b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
6786b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
6787b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
6788b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
678942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
679042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
679142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
679242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
679442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
679542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
679642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
679742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
679842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
680042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
680142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
680242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
680342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
680442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
680542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
680642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
680742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
680842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
680942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
681042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
681142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
681242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
681342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
68148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount,
68158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "4:12");
68168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
681742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
68188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccount,
68198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "3:4%121");
68208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doh");
682142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
682242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
682342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
682442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
682542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
682642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
682742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
682842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
682942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
683042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
683142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
683242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
683342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
683442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
683542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
683642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
683742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
683842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
683942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
684042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
684142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
684242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
684442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
684542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
684642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
684742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
684842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
685042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
685142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
685242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
685342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
685442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
685542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
685642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
685742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
685842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
685942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
686042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
686142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
686242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
686342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
686442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
686542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
686642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
686742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
686842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
686942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
687042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
687142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
687242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
687324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
687424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
687524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
687624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
687724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
687824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
687924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
688024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
688124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
688224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
688342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
688442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
688542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
688642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
688742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
688842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
688942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
689042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
689142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
689242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
689342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
689442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
689542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
689642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
689742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
689842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
689942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
690042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
690142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
690242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
690342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
690442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
690542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
690642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
690742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
690842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
690942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
691024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
691124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
691224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
691342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
691442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
691542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
691642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
691742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
691842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
691942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
692042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
692142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
692242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
692342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
692442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
692542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
692642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
692742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6928dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
6929dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6930dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6931dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
6932dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
69338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
69348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, null);
6936dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6937dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6938dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6939dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6940dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6941dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6942dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6943dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6944dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6945dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6946dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6947dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6948dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6949dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6950dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
6951dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
6952dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6953dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6954dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6955dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6956dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6957dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6958dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
69598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
69608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount);
69628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null);
6965dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6966dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6967dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6968dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6969dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6970dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6971dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
6972dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6973dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6974dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6975dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6976dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6977dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
6978dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
6979dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
6980dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
6981dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
6982dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
69838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo, RawContacts.STARRED, "1");
69878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null, RawContacts.STARRED, "1");
69898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r7 = RawContactUtil.createRawContact(mResolver, null);
6990dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6991dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6992dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6993dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6994dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6995dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6996dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
6997dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6998dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6999dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7000dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7001dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
7002dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
7003dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
7004dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
7005dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7006dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7007dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7008dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7009dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7010dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7011dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7012dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7013dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7014dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7015dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7016dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7017dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7018dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7019dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7020dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
7021dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
7022dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
7023dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7024dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7025dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7026dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7027dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7028dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7029dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7030dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7031dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7032dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7033dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7034dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
7035dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7036dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7037dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7038dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7039dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7040dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
7041dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7042dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7043dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7044dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7045dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7046dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7047dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7048dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
7049dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
7050dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
7051dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
7052dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7053dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7054dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
7055dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7056dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7057dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7058dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
70598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
70608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
70618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7062dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7063dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7064dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7065dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7066dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7067dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7068dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7069dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7070dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7071dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7072dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7073dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7074dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7075dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7076dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7077dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7078dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7079dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7080dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7081dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
7082dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
7083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7084dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7085dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7086dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7087dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7088dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7090dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7091dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7098dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7099dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7100dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7101dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7102dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7103e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
7104dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
7105dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7106dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
7107dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
7108dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7109dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7110dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7111dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7112dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7113dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7114dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7115dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7116dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7117dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7118dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7119dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7120dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7121dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7122dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7123dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
7124dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7125dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7126dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7127dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7128dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7129dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
7130dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7131dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7132dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7133dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
71348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
71358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
71368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7141dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7142dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
7143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7144dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
7145dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
7146dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
7147dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
7148dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7149dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7150dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7151dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7152dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7153dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7154dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7155dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7156dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7157dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7158dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7159dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7160dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7161dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7162dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
7163dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
7164dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
7165dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7166dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7167dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7168dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
7169dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7170dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7171dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7172dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
7173dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
7174dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
7175dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7176dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7177dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7178dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7179dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
7180dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7181dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7182dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
7183dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7184dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7185dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7186dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7187dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7188dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7189dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
7190dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
7191dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
7192dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7193dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7194dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7195dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7196dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7197dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7198dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
719997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
72008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
720197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
720297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
720397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
720497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
720597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
720697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
720797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
720897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
720997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
721097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
721197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
721297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
721397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
721497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
721597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
72168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
721797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
721897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
721997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
722097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
722197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
722297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
722397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
722497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
722597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
722697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
722797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
722897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
722997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
723097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
723197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
723297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
723397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
72348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
723597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
723697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
723797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
72388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
723997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
724097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
724197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
724297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
724397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
724497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
724597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
724697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
724797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
724897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
724997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
725097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
725197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
725297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
725397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
725497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
72557a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
72567a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
72577a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
72587a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72597a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
72607a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
726117a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
72627a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72637a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72647a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72657a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72667a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72677a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72687a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72697a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72707a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72717a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
72727a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
72737a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
72747a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
72757a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
72767a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
72777a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
72787a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
72797a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
72807a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72817a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
728255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
72837a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
72847a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72857a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72867a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72877a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72887a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72897a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72907a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72917a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72927a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72937a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
7294084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    public void testBuildSingleRowResult() {
7295084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7296084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b"},
7297084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7298084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7299084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2}
7300084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7301084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7302084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7303084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b", "a", "b"},
7304084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7305084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7306084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2, 1, 2}
7307084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7308084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7309084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7310084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                null, // all columns
7311084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7312084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7313084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2}
7314084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7315084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7316084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7317084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            // Access non-existent column
7318084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            ContactsProvider2.buildSingleRowResult(new String[] {"a"}, new String[] {"b"},
7319084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                    new Object[] {1});
7320084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            fail();
7321084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } catch (IllegalArgumentException expected) {
7322084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7323084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7324084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7325084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    private void checkBuildSingleRowResult(String[] projection, String[] availableColumns,
7326084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            Object[] data, Integer[] expectedValues) {
7327084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        final Cursor c = ContactsProvider2.buildSingleRowResult(projection, availableColumns, data);
7328084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7329084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertTrue(c.moveToFirst());
7330084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(1, c.getCount());
7331084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(expectedValues.length, c.getColumnCount());
7332084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7333084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            for (int i = 0; i < expectedValues.length; i++) {
7334084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                assertEquals("column " + i, expectedValues[i], (Integer) c.getInt(i));
7335084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            }
7336084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } finally {
7337084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            c.close();
7338084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7339084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7340084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7341dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    public void testDataUsageFeedbackAndDelete() {
7342dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7343dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.install();
7344d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(System.currentTimeMillis());
7345dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long startTime = sMockClock.currentTimeMillis();
7346dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "contact", "a");
7348dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1a = ContentUris.parseId(insertEmail(rid1, "email_1_a@email.com"));
7349dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1b = ContentUris.parseId(insertEmail(rid1, "email_1_b@email.com"));
7350dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1p = ContentUris.parseId(insertPhoneNumber(rid1, "555-555-5555"));
7351dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "contact", "b");
7353dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2a = ContentUris.parseId(insertEmail(rid2, "email_2_a@email.com"));
7354dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2p = ContentUris.parseId(insertPhoneNumber(rid2, "555-555-5556"));
7355dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7356dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Aggregate 1 and 2
7357dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rid1, rid2);
7358dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContactWithName(mResolver, "contact", "c");
7360dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3a = ContentUris.parseId(insertEmail(rid3, "email_3@email.com"));
7361dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3p = ContentUris.parseId(insertPhoneNumber(rid3, "555-3333"));
7362dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContactWithName(mResolver, "contact", "d");
7364dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did4p = ContentUris.parseId(insertPhoneNumber(rid4, "555-4444"));
7365dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7366dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid1 = queryContactId(rid1);
7367dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid3 = queryContactId(rid3);
7368dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid4 = queryContactId(rid4);
7369dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7370dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Make sure 1+2, 3 and 4 aren't aggregated
7371dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid3);
7372dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid4);
7373dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid3, cid4);
7374dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7375dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime
7376dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7377a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // First, there's no frequent.  (We use strequent here only because frequent is hidden
7378a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // and may be removed someday.)
7379a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7380a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7381dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 1. touch data 1a
7382dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a);
7383a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7384dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, there's a single frequent.  (contact 1)
7385a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(1, Contacts.CONTENT_STREQUENT_URI, null, null);
7386a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7387dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 1
7388dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7389dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7390dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 1a, 2a and 3a
7391dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a, did2a, did3a);
7392dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7393dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, contact 1 and 3 are in frequent.
7394dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7395dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7396dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 2
7397dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7398dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7399dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 2p (call)
7400dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did2p);
7401dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7402dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // There're still two frequent.
7403dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7404dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7405dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 3
7406dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7407dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7408dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 3. touch data 2p and 3p (short text)
7409dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, did2p, did3p);
7410dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7411dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's check the tables.
7412dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7413dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Fist, check the data_usage_stat table, which has no public URI.
7414dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7415dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.USAGE_TYPE_INT +
7416dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.TIMES_USED +
7417dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.LAST_TIME_USED +
7418dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7419dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did1a,
7420dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7421dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7422dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 2,
7423dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7424dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7425dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2a,
7426dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7427dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7428dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7429dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7430dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7431dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3a,
7432dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7433dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7434dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7435dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7436dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7437dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7438dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7439dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_CALL,
7440dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7441dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 2
7442dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7443dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7444dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7445dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7446dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7447dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7448dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7449dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3p,
7450dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7451dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7452dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7453dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7454dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7455dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7456dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7457dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Next, check the raw_contacts table
7458dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
7459dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid1,
7460dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7461dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 1
7462dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7463dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid2,
7464dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 3,
7465dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7466dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7467dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid3,
7468dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7469dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7470dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7471dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid4,
7472dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0,
7473dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, null // 4 wasn't touched.
7474dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7475dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7476dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7477dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Lastly, check the contacts table.
7478dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7479dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Note contact1.TIMES_CONTACTED = 4, even though raw_contact1.TIMES_CONTACTED +
7480dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // raw_contact1.TIMES_CONTACTED = 5, because in test 2, data 1a and data 2a were touched
7481dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // at once.
7482dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
7483dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid1,
7484dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 4,
7485dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7486dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7487dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid3,
7488dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 2,
7489dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7490dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7491dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid4,
7492dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 0,
7493dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, 0 // For contacts, the default is 0, not null.
7494dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7495dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7496a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7497dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's test the delete too.
7498b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7499a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7500a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Now there's no frequent.
7501a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7502a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7503dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // No rows in the stats table.
7504dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7505dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7506dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                new ContentValues[0]);
7507dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7508a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // The following values should all be 0 or null.
7509a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
7510a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.LAST_TIME_CONTACTED + ">0", null);
7511a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
7512a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.LAST_TIME_CONTACTED + ">0", null);
7513a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7514a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Calling it when there's no usage stats will still return a positive value.
7515b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7516a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki    }
7517a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
75188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /*******************************************************
75198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Delta api tests.
75208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
75218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_hasDeleteLog() {
75228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long start = sMockClock.currentTimeMillis();
75248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
75258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, start);
75268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up. Must also remove raw contact.
75288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_marksRawContactsForDeletion() {
75328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
75338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        String[] projection = new String[]{ContactsContract.RawContacts.DIRTY,
75358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.RawContacts.DELETED};
75368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        List<String[]> records = RawContactUtil.queryByContactId(mResolver, ids.mContactId,
75378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                projection);
75388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] arr : records) {
75398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[0]);
75408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[1]);
75418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
75428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactUpdate_updatesContactUpdatedTimestamp() {
75488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
75548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.Contacts.STARRED, 1);
75558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.update(mResolver, ids.mContactId, values);
75588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    // This implicitly tests the Contact create case.
75678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactCreate_updatesContactUpdatedTimestamp() {
75688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long startTime = System.currentTimeMillis();
75698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
75718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long lastUpdated = getContactLastUpdatedTimestampByRawContactId(mResolver, rawContactId);
75728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(lastUpdated > startTime);
75748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, rawContactId, true);
75778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
75808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
75858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.RawContacts.STARRED, 1);
75868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.update(mResolver, ids.mRawContactId, values);
75878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactPsuedoDelete_hasDeleteLogForContact() {
75968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, false);
76018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
76038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // clean up
76058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactDelete_hasDeleteLogForContact() {
76098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
76168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // already clean
76188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long getContactLastUpdatedTimestampByRawContactId(ContentResolver resolver,
76218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            long rawContactId) {
76228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long contactId = RawContactUtil.queryContactIdByRawContactId(mResolver, rawContactId);
76238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
76248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
76268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataInsert_updatesContactLastUpdatedTimestamp() {
76298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
76348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        insertPhoneNumberAndReturnDataId(ids.mRawContactId);
76358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataDelete_updatesContactLastUpdatedTimestamp() {
76448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
76488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
76528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.delete(mResolver, dataId);
76538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataUpdate_updatesContactLastUpdatedTimestamp() {
76628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
76668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
76708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
76718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "555-5555");
76728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.update(mResolver, dataId, values);
76738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long insertPhoneNumberAndReturnDataId(long rawContactId) {
76828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = insertPhoneNumber(rawContactId, "1-800-GOOG-411");
76838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContentUris.parseId(uri);
76848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsDelete_isUnsupported() {
76878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, URI);
76898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = ContentUris.withAppendedId(URI, 1L);
76918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, uri);
76928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsInsert_isUnsupported() {
76958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertInsertIsUnsupported(mResolver, URI);
76978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsByContactId() {
77018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
77028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND,
77048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
77058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
77068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsAll() {
77088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final int numDeletes = 10;
77098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Since we cannot clean out delete log from previous tests, we need to account for that
77118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // by querying for the count first.
77128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long startCount = DeletedContactUtil.getCount(mResolver);
77138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (int i = 0; i < numDeletes; i++) {
77158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertContactCreateDelete();
77168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
77178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long endCount = DeletedContactUtil.getCount(mResolver);
77198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(numDeletes, endCount - startCount);
77218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
77228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsSinceTimestamp() {
77248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
77258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Before
77278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> beforeIds = new HashSet<Long>();
77288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
77298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
77308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long start = sMockClock.currentTimeMillis();
77328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // After
77348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> afterIds = new HashSet<Long>();
77358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
77368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
77378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
77388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final String[] projection = new String[]{
77408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_ID,
77418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
77428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        };
77438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final List<String[]> records = DeletedContactUtil.querySinceTimestamp(mResolver, projection,
77448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                start);
77458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] record : records) {
77468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check ids to make sure we only have the ones that came after the time.
77478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            final long contactId = Long.parseLong(record[0]);
77488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertFalse(beforeIds.contains(contactId));
77498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(afterIds.contains(contactId));
77508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check times to make sure they came after
77528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(Long.parseLong(record[1]) > start);
77538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
77548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
77558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
77578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Create a contact. Assert it's not present in the delete log. Delete it.
77588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * And assert that the contact record is no longer present.
77598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     *
77608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * @return The contact id and raw contact id that was created.
77618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
77628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private DatabaseAsserts.ContactIdPair assertContactCreateDelete() {
77638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
77648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(CommonDatabaseUtils.NOT_FOUND,
77668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
77678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
77698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.delete(mResolver, ids.mContactId);
77708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertFalse(ContactUtil.recordExistsForContactId(mResolver, ids.mContactId));
77728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ids;
77748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
777581fea08280784b319b936a3506788d595c6ce2adYorke Lee
77768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
77778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * End delta api tests.
77788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     ******************************************************/
77798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
778081fea08280784b319b936a3506788d595c6ce2adYorke Lee    /*******************************************************
778181fea08280784b319b936a3506788d595c6ce2adYorke Lee     * Pinning support tests
778281fea08280784b319b936a3506788d595c6ce2adYorke Lee     */
778381fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateForceStar() {
778481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
778581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
778681fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
778781fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
778881fea08280784b319b936a3506788d595c6ce2adYorke Lee
778981fea08280784b319b936a3506788d595c6ce2adYorke Lee        final int unpinned = PinnedPositions.UNPINNED;
779081fea08280784b319b936a3506788d595c6ce2adYorke Lee
779181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
779281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
779381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
779481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
779581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0)
779681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
779781fea08280784b319b936a3506788d595c6ce2adYorke Lee
779881fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
779981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, unpinned),
780081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
780181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned),
780281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, unpinned)
780381fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
780481fea08280784b319b936a3506788d595c6ce2adYorke Lee
780581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, 2);
780681fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
780781fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
780881fea08280784b319b936a3506788d595c6ce2adYorke Lee                values, null, null);
780981fea08280784b319b936a3506788d595c6ce2adYorke Lee
781081fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Pinning a contact should automatically star it if we specified the boolean parameter
781181fea08280784b319b936a3506788d595c6ce2adYorke Lee
781281fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
781381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
781481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
781581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 1),
781681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 1)
781781fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
781881fea08280784b319b936a3506788d595c6ce2adYorke Lee
781981fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Make sure the values are propagated to raw contacts
782081fea08280784b319b936a3506788d595c6ce2adYorke Lee
782181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
782281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
782381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
782481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
782581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2)
782681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
782781fea08280784b319b936a3506788d595c6ce2adYorke Lee
782881fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues unpin = cv(i3.mContactId, unpinned);
782981fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
783081fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
783181fea08280784b319b936a3506788d595c6ce2adYorke Lee                unpin, null, null);
783281fea08280784b319b936a3506788d595c6ce2adYorke Lee
783381fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Unpinning a contact should automatically unstar it
783481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
783581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
783681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
783781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
783881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 1)
783981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
784081fea08280784b319b936a3506788d595c6ce2adYorke Lee
784181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
784281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mRawContactId, RawContacts.PINNED, 1, RawContacts.STARRED, 1),
784381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
784481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
784581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned,
784681fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
784781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mRawContactId, RawContacts.PINNED, 2, RawContacts.STARRED, 1)
784881fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
784981fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
785081fea08280784b319b936a3506788d595c6ce2adYorke Lee
785181fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateDontForceStar() {
785281fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
785381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
785481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
785581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
785681fea08280784b319b936a3506788d595c6ce2adYorke Lee
785781fea08280784b319b936a3506788d595c6ce2adYorke Lee        final int unpinned = PinnedPositions.UNPINNED;
785881fea08280784b319b936a3506788d595c6ce2adYorke Lee
785981fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, 2);
786081fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
786181fea08280784b319b936a3506788d595c6ce2adYorke Lee
786281fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Pinning a contact should not automatically star it
786381fea08280784b319b936a3506788d595c6ce2adYorke Lee
786481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
786581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
786681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
786781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 0),
786881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
786981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
787081fea08280784b319b936a3506788d595c6ce2adYorke Lee
787181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Make sure the values are propagated to raw contacts
787281fea08280784b319b936a3506788d595c6ce2adYorke Lee
787381fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
787481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
787581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
787681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
787781fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
787881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
787981fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
788081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2,
788181fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
788281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
788381fea08280784b319b936a3506788d595c6ce2adYorke Lee
788481fea08280784b319b936a3506788d595c6ce2adYorke Lee
788581fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Manually star contact 3
788681fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertEquals(1, updateItem(Contacts.CONTENT_URI, i3.mContactId, Contacts.STARRED, "1"));
788781fea08280784b319b936a3506788d595c6ce2adYorke Lee
788881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Check the third contact and raw contact is starred
788981fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
789081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
789181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
789281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 1),
789381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
789481fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
789581fea08280784b319b936a3506788d595c6ce2adYorke Lee
789681fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
789781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
789881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
789981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
790081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
790181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
790281fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
790381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2,
790481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
790581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
790681fea08280784b319b936a3506788d595c6ce2adYorke Lee
790781fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues unpin = cv(i3.mContactId, unpinned);
790881fea08280784b319b936a3506788d595c6ce2adYorke Lee
790981fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, unpin, null, null);
791081fea08280784b319b936a3506788d595c6ce2adYorke Lee
791181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Unpinning a contact should not automatically unstar it
791281fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
791381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
791481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
791581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 1),
791681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
791781fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
791881fea08280784b319b936a3506788d595c6ce2adYorke Lee
791981fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
792081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mRawContactId, RawContacts.PINNED, 1, RawContacts.STARRED, 0),
792181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
792281fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
792381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned,
792481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
792581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mRawContactId, RawContacts.PINNED, 2, RawContacts.STARRED, 0)
792681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
792781fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
792881fea08280784b319b936a3506788d595c6ce2adYorke Lee
792981fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateIllegalValues() {
793081fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
793181fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
793281fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
793381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
793481fea08280784b319b936a3506788d595c6ce2adYorke Lee
793581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
793681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
793781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
793881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
793981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
794081fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
794181fea08280784b319b936a3506788d595c6ce2adYorke Lee
794245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Unsupported string
794345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId,
794445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                "undemotemeplease!");
794581fea08280784b319b936a3506788d595c6ce2adYorke Lee        try {
794681fea08280784b319b936a3506788d595c6ce2adYorke Lee            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
794745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            fail("Pinned position must be an integer.");
794881fea08280784b319b936a3506788d595c6ce2adYorke Lee        } catch (IllegalArgumentException expected) {
794981fea08280784b319b936a3506788d595c6ce2adYorke Lee        }
795081fea08280784b319b936a3506788d595c6ce2adYorke Lee
795145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Float
795245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values2 = cv(i1.mContactId, "1.1");
795381fea08280784b319b936a3506788d595c6ce2adYorke Lee        try {
795445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values2, null, null);
795545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            fail("Pinned position must be an integer");
795681fea08280784b319b936a3506788d595c6ce2adYorke Lee        } catch (IllegalArgumentException expected) {
795781fea08280784b319b936a3506788d595c6ce2adYorke Lee        }
795881fea08280784b319b936a3506788d595c6ce2adYorke Lee
795981fea08280784b319b936a3506788d595c6ce2adYorke Lee        // nothing should have been changed
796081fea08280784b319b936a3506788d595c6ce2adYorke Lee
796181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
796281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
796381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
796481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
796581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
796681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
796781fea08280784b319b936a3506788d595c6ce2adYorke Lee
796881fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
796981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
797081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
797181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
797281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED)
797381fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
797481fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
797581fea08280784b319b936a3506788d595c6ce2adYorke Lee
797681fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsAfterJoinAndSplit() {
797781fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
797881fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
797981fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
798081fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
798145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i5 = DatabaseAsserts.assertAndCreateContact(mResolver);
798245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i6 = DatabaseAsserts.assertAndCreateContact(mResolver);
798381fea08280784b319b936a3506788d595c6ce2adYorke Lee
798445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 1, i2.mContactId, 2, i3.mContactId, 3,
798545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                i5.mContactId, 5, i6.mContactId, 6);
798681fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
798781fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
798881fea08280784b319b936a3506788d595c6ce2adYorke Lee                values, null, null);
798981fea08280784b319b936a3506788d595c6ce2adYorke Lee
799081fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 1 and 4 together.
799181fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i1.mRawContactId,
799281fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
799381fea08280784b319b936a3506788d595c6ce2adYorke Lee
799481fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If only one contact is pinned, the resulting contact should inherit the pinned position
799581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
799681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
799781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
799845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3),
799945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
800045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
800181fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
800281fea08280784b319b936a3506788d595c6ce2adYorke Lee
800381fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
800481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
800581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
800681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
800781fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
800881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
800981fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
801081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
801145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
801245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
801345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
801445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
801545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
801681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
801781fea08280784b319b936a3506788d595c6ce2adYorke Lee
801881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 2 and 3 together.
801981fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i2.mRawContactId,
802081fea08280784b319b936a3506788d595c6ce2adYorke Lee                i3.mRawContactId);
802181fea08280784b319b936a3506788d595c6ce2adYorke Lee
802281fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If both raw contacts are pinned, the resulting contact should inherit the lower
802381fea08280784b319b936a3506788d595c6ce2adYorke Lee        // pinned position
802481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
802581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
802645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
802745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
802845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
802981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
803081fea08280784b319b936a3506788d595c6ce2adYorke Lee
803181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
803281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
803381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2),
803481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
803545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED,
803645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        PinnedPositions.UNPINNED),
803745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5),
803845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6)
803981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
804081fea08280784b319b936a3506788d595c6ce2adYorke Lee
804181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // split the aggregated raw contacts
804281fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE, i1.mRawContactId,
804381fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
804481fea08280784b319b936a3506788d595c6ce2adYorke Lee
804581fea08280784b319b936a3506788d595c6ce2adYorke Lee        // raw contacts should be unpinned after being split, but still starred
804681fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
804781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
804881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
804981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
805081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
805181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
805281fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
805381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
805445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
805545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
805645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
805745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
805845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
805945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
806045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
806145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
806245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
806345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // now demote contact 5
806445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues cv = cv(i5.mContactId, PinnedPositions.DEMOTED);
806545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().build(),
806645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv, null, null);
806745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
806845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Get new contact Ids for contacts composing of raw contacts 1 and 4 because they have
806945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // changed.
807045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
807145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
807245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
807345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
807445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
807545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
807645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
807745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED),
807845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
807945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
808045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
808145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // aggregate contacts 5 and 6 together
808245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i5.mRawContactId,
808345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                i6.mRawContactId);
808445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
808545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // The resulting contact should have a pinned value of 6
808645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
808745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
808845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
808945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
809045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 6)
809145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
809245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    }
809345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
809445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    public void testPinnedPositionsAfterDemoteAndUndemote() {
809545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
809645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
809745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
809845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 0, i2.mContactId, PinnedPositions.DEMOTED);
809945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
810045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Pin contact 1 and demote contact 2
810145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
810245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").
810345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                build(), values, null, null);
810445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
810545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
810645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
810745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED,
810845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
810945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
811045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
811145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
811245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
811345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
811445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.DEMOTED,
811545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0)
811645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
811745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
811845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Now undemote both contacts
811945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values2 = cv(i1.mContactId, PinnedPositions.UNDEMOTE, i2.mContactId,
812045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                PinnedPositions.UNDEMOTE);
812145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
812245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                build(), values2, null, null);
812345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
812445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Contact 1 remains pinned at 0, while contact 2 becomes unpinned
812545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
812645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
812745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED,
812845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
812945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
813045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
813145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
813245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
813345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
813445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
813581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
813681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
813781fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
813881fea08280784b319b936a3506788d595c6ce2adYorke Lee
813981fea08280784b319b936a3506788d595c6ce2adYorke Lee    /**
814081fea08280784b319b936a3506788d595c6ce2adYorke Lee     * End pinning support tests
814181fea08280784b319b936a3506788d595c6ce2adYorke Lee     ******************************************************/
81428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
8143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
81448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Cursor c = mResolver.query(TestUtil.maybeAddAccountQueryParameters(Data.CONTENT_URI,
81458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account),
8146dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
8147dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
8148dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
8149dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
8150dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
8151dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
815242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
815342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
8154bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
815542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
815642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
8157bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
8158bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
8159bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
8160bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
8161bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
8162bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
8163bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
816442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
8165bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
8166bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
816742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
816842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
816942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
817042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
817142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
817242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
8173f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
8174f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
8175f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
8176f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
8177f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
81784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
81794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8180aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
818124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
818224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
818324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
818424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
818524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
818624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
818724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
818848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
818924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
819048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
819148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
819248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
819348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8194aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
819548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
8196aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
81978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
819848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
819948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
820048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
820124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
820224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
820324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
820424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
820524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
82068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
820724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
820824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
820924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
821048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
8211aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
821224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
821324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
821424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
821524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
821624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
821724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
821824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
82194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
82204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
82214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
82224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
822324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
822424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
822524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
822624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
822724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
82284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
82294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
82304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
82314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
82329dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
82339dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
82349dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
82359dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
82369dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
82379dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
82384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8239aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
82405d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
82414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
82424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
82434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
82444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
824524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
824648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
82474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
82484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
824924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
825024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
825124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
825224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
825324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
825424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
825524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
825624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
825724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
825824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
825924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
826024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
826124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
826224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
826324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
826424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
826524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
826624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
826724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
826824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
826924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
827024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
827124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
827224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
827324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
827424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
827524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
827624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
82774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
82784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
82794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
82804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
82814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
82824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
82834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
82844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
82854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
82864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
82874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
82884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
82894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
82904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
82914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
82924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
82934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
82944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
82954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
82964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
82974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
82984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
82994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
83004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
83014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
83024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
83034928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
83044928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
83054928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
83064928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
83074928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
83084928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
83094928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
83104928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
83114928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
83124928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
8313dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(0, updateDataUsageFeedback(usageType, dataId));
83144928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
83154928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
83164928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
83174928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
8318dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
8319dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    private void updateDataUsageFeedback(String usageType, Uri resultUri) {
8320dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final long id = ContentUris.parseId(resultUri);
8321dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final boolean successful = updateDataUsageFeedback(usageType, id) > 0;
8322dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertTrue(successful);
8323dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
8324dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
8325dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    private int updateDataUsageFeedback(String usageType, long... ids) {
8326dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final StringBuilder idList = new StringBuilder();
8327dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        for (long id : ids) {
8328dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            if (idList.length() > 0) idList.append(",");
8329dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            idList.append(id);
8330dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        }
8331dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        return mResolver.update(DataUsageFeedback.FEEDBACK_URI.buildUpon()
8332dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendPath(idList.toString())
8333dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
8334dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .build(), new ContentValues(), null, null);
8335dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    }
8336a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8337a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasChineseCollator() {
8338a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8339a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8340a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.CHINA)) {
8341a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8342a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8343a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8344a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8345a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
8346a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8347a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasJapaneseCollator() {
8348a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8349a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8350a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.JAPAN)) {
8351a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8352a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8353a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8354a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8355a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
83561f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
83571f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    private boolean hasGermanCollator() {
83581f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
83591f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        for (int i = 0; i < locale.length; i++) {
83601f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            if (locale[i].equals(Locale.GERMANY)) {
83611f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                return true;
83621f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            }
83631f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
83641f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        return false;
83651f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
8366d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
8367