ContactsProvider2Test.java revision 45b023e89d87b66e44c1b79c6e1444ec9db70a82
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,
242a89aa7533a14b143b55bf4a29d284152ab9278a5Yorke Lee                Phone.CONTACT_ID
24363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
24463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
24563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
246dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
251dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
252dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
253dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
254dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
255dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
257a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
258a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
259a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
260a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
261dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
26481fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
265dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
267f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2683d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2693d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
272dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
27324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
274dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
278dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
2838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
28430cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
288dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
29443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
29543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
29824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
299dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
309a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_PRIMARY,
310a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
311a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
312a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
313dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
31881fea08280784b319b936a3506788d595c6ce2adYorke Lee                RawContacts.PINNED,
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
326dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
327dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
328dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
329dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
345dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
346dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
347dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
348dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
349dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
350dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
351dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
352dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
353dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
354dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
355dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
356dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
357dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
358dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
359dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
360dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
361dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
362dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
363216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
364216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
365dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
366dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
36743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
36843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
369dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
370dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
371dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
372dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
37324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
374dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
375dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
376dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
377dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
378dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
379dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
380dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
381dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
382a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
383a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
384a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
385a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
386dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
387dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
388dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
38981fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
390dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
391dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
392f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3933d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3943d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
395dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
396dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
397dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
398dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
399cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
400dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
401dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
402dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
403dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
404dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
405dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
406dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
408dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
409dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
410dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
411dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
412dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
413dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
414dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
415dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
416dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
417dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
418dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
419dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
420dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
421dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
422dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
423dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
424dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
425dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
426dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
427dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
428dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
445dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
446dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
448216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
449216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
45024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
451dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
459a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
460a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
461a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
462a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
463dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
46681fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
469f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4703d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4713d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
472cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
482dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
484dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
485dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
486dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
487dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
488a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
489a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
490a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
491a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
492a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
493a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
494a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
495a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
496a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
497a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
498a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
499a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
500a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
501a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
502a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
503a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
504a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
505a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
506a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
507a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
508a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
509a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
510a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
511a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
512a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
513a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
514a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
515a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
516a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
517a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
518a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
519a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
520a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
521a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
522a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
523a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
524a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
525a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
526a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
527a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
528a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
529a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
53043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
53143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
532a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
533a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
534a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
535a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
536a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
537a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
538a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
539a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
540a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
541a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
542a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
543a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
544a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
545a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
546a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
547a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
548a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
549a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
550a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
551a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
552a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
553a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
554a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
555a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
55681fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
557a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
558a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
559f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
5603d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
5613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
562a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
563a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
56424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
565a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
566a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
567cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
568a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
569a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
570a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
571a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
572a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
573a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
574a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
5758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
576a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
577a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
578a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
579a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
580dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
581dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
58743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
58843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
589dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
59924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
614dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
618dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
619dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
620dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
621dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
622dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
623dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
624dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
625dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
626dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
627dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
628dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
629dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
630dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
631dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
632dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
633dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
634dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
635dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
636dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
637dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
638dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
6393d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
6403d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
641dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
642dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
643dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
644dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
645dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
646dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
6472530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
648dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
649dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
650dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
651dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
652dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
653dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
654dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
655dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
65643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
65743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
658dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
659dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
660dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
661dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
662dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
663dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
664dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
665dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
666dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
667dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
668dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
669dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
670dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
671c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
672dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
673dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
674dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
675dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
676dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
677dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
678dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
679dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
680dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
681dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
682dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
683dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
68443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
68543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
686dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
687dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
688dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
689dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
690dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
691dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
692dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
693dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
694dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
695dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
696dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
697dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
698dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
699c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
700dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
701dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
702dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
703dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
704dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
705dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
70618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
707dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
708dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
709dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
710dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
711dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
712dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
713dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
714dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
715dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
716dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
717dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
718dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
719dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
720dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
721dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
722dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
723f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET,
724dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
725dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
726dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
727dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
728dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
729dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
730dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
731dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
732dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
733dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
734dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
735dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
736dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
737dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
738dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
739dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
740dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
741dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
742dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
743dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
744dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
745dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
746dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
747dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
748dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
749dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
750dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
751dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
752dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
753dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
754dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
755dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
756dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
757dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
758dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
759dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
760778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
761778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
762dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
763dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
764dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
7653cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
7663cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
7673cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7683cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
7693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
7709d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(RawContacts.DATA_SET, "ds");
7713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
7723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
7733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
7743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
7753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
7763cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
7773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
7783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
7793cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
7803cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
7813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
7823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
7833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
7843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
7864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
7873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
7894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
79081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
7913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
7923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7932149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
7942149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
7952149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
7972149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
7982149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
7992149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8002149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8012149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
8022149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8032149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
8042149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
8052149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8062149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8072149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8082149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8092149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
8102149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
8112149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8122149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8132149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8142149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
8152149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
8162149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
8172149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8182149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8192149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8202149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
8212149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
8222149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
8232149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
8242149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
8252149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8262149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8272149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8282149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
8292149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8302149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8312149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8322149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
8332149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8342149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8352149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
8362149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8372149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
838a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
839a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
840a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
841a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
842a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
844a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
845a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8465d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
847a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
849a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
850a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
851a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
852a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
853a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
854a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
855a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
856a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
857a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
858a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
859a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
860a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
861a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
862a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
863a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
864a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
866a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
867a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8685d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
869a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
871a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
872a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
873a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
874a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
875a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
876a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
877a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
878a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
879a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
880a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
881a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
882a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
883a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
884a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
885a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
886a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
887a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
888a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
889a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
890a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
891a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
892a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
893a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
894a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
895a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
896a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
897a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
898a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
899a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
900a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
901a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
902a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
903a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
904a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
905a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
906a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
907a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
908a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
909a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
910a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
911a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
912a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
913a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
914a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
915a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
916a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
917a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
918a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
919a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
920a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
921a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
922a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
923a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
924a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
925a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
926a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
927a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
928a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
929a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
930a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
931a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
932a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
933a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
934a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
935a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
936a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
937a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
938a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
939a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
940a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
941a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
942a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
943a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
944a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
945a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
946a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
947a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
948a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
949a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
950a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
951a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
952a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
953a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
954a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
955a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
9563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
9578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
9584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
9604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
9614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
9624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
9634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
9654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
9664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
9674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
9694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
9714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
9724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
9734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
9744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
9754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
9774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
9784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
9794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
98081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
9814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
9823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
98389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
98489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
98589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
9868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
9878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
9888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
9898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doe");
99089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(dataUri1, account1);
9928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(dataUri2, account2);
99389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
99489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
99589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
99689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
9987d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
9993cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
10004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
10014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
10024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
10034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
10044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
10054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
10074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
10084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
10104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
10124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
10173cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
10204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
10214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
10224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
10234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
10264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
10274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
10284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
10294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
103048828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
10314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
10324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1034cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    public void testPhonesWithMergedContacts() {
10358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1036cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "123456789", true);
1037cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
1039cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "123456789", true);
1040cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10410992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
10420992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki                rawContactId1, rawContactId2);
10430992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        assertNotAggregated(rawContactId1, rawContactId2);
10440992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki
1045cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1046cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "123456789");
1047cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1048cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Phone.NUMBER, "123456789");
1049cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10500992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // There are two phone numbers, so we should get two rows.
1051cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
1052cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10530992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now set the dedupe flag.  But still we should get two rows, because they're two
10540992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // different contacts.  We only dedupe within each contact.
10558ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Phone.CONTENT_URI.buildUpon()
10568ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
10578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
10588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, new ContentValues[] {values1, values1});
10598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10600992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now join them into a single contact.
1061cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
1062cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa                rawContactId1, rawContactId2);
1063cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1064cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertAggregated(rawContactId1, rawContactId2, "123456789");
1065cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10660992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Contact merge won't affect the default result of Phone Uri, where we don't dedupe.
10678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
10688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10690992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now we dedupe them.
10708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values1);
1071cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    }
1072cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1073904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    public void testPhonesNormalizedNumber() {
10748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver);
1075904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1076904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Write both a number and a normalized number. Those should be written as-is
1077904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final ContentValues values = new ContentValues();
1078904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.RAW_CONTACT_ID, rawContactId);
1079904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1080904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1234");
1081904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "5678");
1082904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.TYPE, Phone.TYPE_HOME);
1083904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1084904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
1085904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
108610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the lookup table.
1087904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1088904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1089904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1090904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1091904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
109210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the data table.
109310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
109410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1234", Phone.NORMALIZED_NUMBER, "5678")
109510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
109610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1097904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace both in an UPDATE
1098904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1099904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "4321");
1100904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1101904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1102904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1103904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1104904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1105904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "4321"), null, null));
1106904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1107904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1108904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1109904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1110904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
111110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
111210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "4321", Phone.NORMALIZED_NUMBER, "8765")
111310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
111410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1115904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NUMBER ==> NORMALIZED_NUMBER will be inferred (we test that by making
1116904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // sure the old manual value can not be found anymore)
1117904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
111810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "+1-800-466-5432");
1119904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1120904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1121904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
112210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1123904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1124904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1125904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1126904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
112710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
112810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
112910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
113010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1131904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NORMALIZED_NUMBER ==> call is ignored, things will be unchanged
1132904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1133904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1134904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1135904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1136904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
113710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1138904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1139904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1140904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
114110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
114310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
114410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
114510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Replace NUMBER with an "invalid" number which can't be normalized.  It should clear
114710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // NORMALIZED_NUMBER.
114810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 1. Set 999 to NORMALIZED_NUMBER explicitly.
115010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
115110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "888");
115210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NORMALIZED_NUMBER, "999");
115310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
115410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(1,
115610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
115710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
115910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "888", Phone.NORMALIZED_NUMBER, "999")
116010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
116110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
116210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 2. Set an invalid number to NUMBER.
116310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
116410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "1");
116510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
116610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
116710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(0,
116810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
116910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
117010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
117110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1", Phone.NORMALIZED_NUMBER, null)
117210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
1173904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    }
1174904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
11754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
1176e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
1177e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1178e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1179e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
1180e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
1181e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
1182e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1183e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
1184e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
1185e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1186e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
1187e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
1188e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
1189e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
1190e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
1191e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
1192e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
1193e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
11948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot",
11958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale", TestUtil.ACCOUNT_1);
11965e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
11975e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Chilled",
11998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Guacamole", TestUtil.ACCOUNT_2);
12002a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
120158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
120258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
12035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1204e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
12054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
12064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
12074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
12085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
12094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
12104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
12115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
12124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1213e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
12145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
12155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1216e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
12175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
12185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1219e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
12205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
122145d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
1222e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
122345d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
122458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
122558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
122658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
122758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
122858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
122958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
123058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
123158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
123258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
123358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
123458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
123558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
123658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
123758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
123858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
123958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
124058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
124158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
124258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
124358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
124458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
124558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
1246e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
1247dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValues(filterUri6, new ContentValues[]{values1, values2, values3});
1248e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1249e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
1250e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1251e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1252e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1253e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1254e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1255e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1256e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1257e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1258e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1259e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1260e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1261e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1262e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1263e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1264e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1265e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1266e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1267e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1268e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1269e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1270e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1271e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1272e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1273e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1274e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1275e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1276e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1277e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1278e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1279e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1280e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
128158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
12824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
12834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12844c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    public void testPhonesFilterSearchParams() {
12858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "Dad", null);
12864c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid1, "123-456-7890");
12874c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "Mam", null);
12894c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid2, "323-123-4567");
12904c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12914c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // By default, "dad" will match both the display name and the phone number.
12924c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // Because "dad" is "323" after the dialpad conversion, it'll match "Mam" too.
12934c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12944c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad").build(),
12954c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890"),
12964c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
12974c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
12984c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12994c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13004c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
13014c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13024c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890")
13034c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13044c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
13054c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13064c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13074c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
13084c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13094c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
13104c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13114c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13124c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
1313dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
1314dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
1315dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .build()
1316dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        );
13174c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    }
13184c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
1319e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1320e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1321e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1322e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1323e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1324e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1325e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1326e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
13278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
13284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
13294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1330ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1331ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1332ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
13334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1334e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1335e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1336e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1337e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1338e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1339e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1340e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1341e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1342e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1343ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
13444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1345892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
134634984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1347e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
134834984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
13496db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13506db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // A wrong area code 799 vs 800 should not be matched
13516db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "7994664411");
13526db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
1353892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1354892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1355892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1356892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1357892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1358892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1359892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1360892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1361892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1362892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1363892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1364892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1365892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1366892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1367892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1369892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1370892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1371892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1372892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1373892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1374892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1375892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1376892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1377892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1378892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1379892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1380892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13816db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with wrong area code
13826db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "649 861 0000");
13836db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13846db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13856db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digits in mistyped area code
13866db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "5 861 0000");
13876db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13886db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13896db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digit in mistyped area code
13906db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "65 861 0000");
13916db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13926db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
1393892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1394892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1395892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1396892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1397892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1398892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1399892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
14008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot1", "Tamale");
1401892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1402892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1403892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1404892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1405892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1406892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1407892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1408892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1409892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1410892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1411892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1412892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1413892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1414892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1415892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1416892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1417892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1418892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1419892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
14208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot2", "Tamale");
1421892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1422892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1423892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1424892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1425892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1426892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1427892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1428892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1429892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1430892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1431892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
14324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
143456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
14356db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Checks the logic that relies on phone_number_compare_loose(Gingerbread) as a fallback
14366db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        //for phone number lookups.
143756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
143856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
143956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
144056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
144156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
144256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
144456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
144556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
144656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
144756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
144856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
144956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
145156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
145256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
145356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
14546db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Number with international (+972) prefix should also match.
14556db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(1, getCount(Uri.withAppendedPath(
14566db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee                PhoneLookup.CONTENT_FILTER_URI, "+97297427289"), null, null));
145756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
145956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
146056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
146156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
146356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
146456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
146556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
146756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
146856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
146956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
147056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
147256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
147356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
147456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
147656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
147756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
147856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
148056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
148156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
148456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
148756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
149056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
149156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
149256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
149356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
149456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
149556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
149656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
149756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1498a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    public void testPhoneLookupUseStrictPhoneNumberCompare() {
1499a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Test lookup cases when mUseStrictPhoneNumberComparison is true
1500a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
1501a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
1502a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Get and save the original value of mUseStrictPhoneNumberComparison so that we
1503a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // can restore it when we are done with the test
1504a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
1505a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
1506a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1507a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1508a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        try {
1509a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            String fullNumber = "01197297427289";
1510a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            ContentValues values = new ContentValues();
1511a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.CUSTOM_RINGTONE, "d");
1512a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1513a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            long rawContactId = ContentUris.parseId(
1514a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    mResolver.insert(RawContacts.CONTENT_URI, values));
15158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
1516a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, fullNumber);
1517a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "5103337596");
1518a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "+19012345678");
1519a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for full number
1520a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1521a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
1522a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1523a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra digit at the front
1524a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1525a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
1526a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for mispelled area code
1527a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1528a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
1529a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1530a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with dashes
1531a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1532a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
1533a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1534a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with international code
1535a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1536a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
1537a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1538a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1539a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra 0 in front
1540a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1541a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
1542a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1543a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1544a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for different country code
1545a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1546a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
1547a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1548a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        } finally {
1549a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // restore the original value of mUseStrictPhoneNumberComparison
1550a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // upon test completion or failure
1551a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
1552a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        }
1553a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    }
1554a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1555653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1556653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1557653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1558653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1559653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
15608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1561653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1562653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1563653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1564ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
1565ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
1566ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
1567653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1568653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1569653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1570653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1571653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1572ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1573ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
1574653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1575653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1576653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1577653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1578653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1579653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1580ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1581653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1582653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1583653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1584653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1585653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1586653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1587ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1588ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
158981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1590653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1591653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1592e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
1593e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
15948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Meghan", "Knox");
1595e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
1596e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
1597e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
15988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
1599e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
1600e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
1601e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
1602e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1603e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1604e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
1605e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
1606e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
1607e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1608e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
1609e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
1610e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
1611e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
1612e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1613e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
1614e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
1615e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
1616e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
1617e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1618e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
1619e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
1620e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1621e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
1622e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
1623e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1624e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1625e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
1626e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
1627e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1628e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
16294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
16304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
16324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
16334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
16344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
16354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
16364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
16388ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
16394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
16418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
16428ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
16434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16448ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
16454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
16464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
16474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
16484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
16494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
16514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
16534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
16544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
16554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
16564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
16574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
16584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
16594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
166148828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
16638ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16648ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
16658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
16668ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
16678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
16688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
16698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
16718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
16728ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
16738ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16748ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
16758ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16768ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
16778ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
16788ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
16798ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16808ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
16818ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16828ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
16838ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
16848ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
16858ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
16864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16885e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
16898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale");
16904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
16914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16925e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
16934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
16954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
16974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
16994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
17004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
170108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
170208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
170308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
170408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
170508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
17064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
17074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
17085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
17098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
17115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
17165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
17175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
17195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
17205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
17215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
17225e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
17235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
17245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
17255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
17265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
17285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
17295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1730155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
17315e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
17325e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17331e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
17345e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
17355e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17365e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
17375e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
17385e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
17395e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17407d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1741c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1742c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1743c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
17448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1745c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1746c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1747c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1748c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1749c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1750c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1751c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1752c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1753c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1754c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1755c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1756dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, new ContentValues[]{v1, v2, v3});
1757c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1758c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1759c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1760c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1761c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1762c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
17638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1764c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1765c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1766c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1767c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1768c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1769c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1770c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1771c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1772c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1773c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1774c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1775c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
17767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
17777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
17787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
17797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
17808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
17817d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
17828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_2);
17837d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
17847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
17857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
17867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
17877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
17887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
17918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_1.type)
17927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
17937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
17947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17957d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
17978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_2.type)
17987d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
17997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
18007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
18017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
18027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
18038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
18047d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
1805dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri3, new ContentValues[]{v1, v2});
18067d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
18077d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
18088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
18097d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
18107d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
18117d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
18127d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
1813dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1814dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test emails with the same domain as primary account are ordered first.
1815dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1816dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    public void testEmailFilterSameDomainAccountOrder() {
1817dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Account account = new Account("tester@email.com", "not_used");
18188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, account);
1819dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@testemail.com");
1820dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@email.com");
1821dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1822dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1823dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account1@email.com");
1824dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1825dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
1826dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, account.name)
1827dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, account.type)
1828dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .build();
1829dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri1, v2, v1);
1830dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1831dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1832dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1833dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test "default" emails are sorted above emails used last.
1834dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1835c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterSuperPrimaryOverUsageSort() {
18368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1837dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1838dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1839c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true, true);
1840dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1841dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Update account1 and account 2 to have higher usage.
1842dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1843dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1844dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1845dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1846dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1847dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1848dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1849dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1850dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1851dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1852dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, v3, v1, v2);
1853dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1854dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1855c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    /**
1856c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * Test primary emails are sorted below emails used last.
1857c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     *
1858c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * primary may be set without super primary.  Only super primary indicates "default" in the
1859c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * contact ui.
1860c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     */
1861c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterUsageOverPrimarySort() {
18628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1863c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1864c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1865c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true);
1866c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1867c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Update account1 and account 2 to have higher usage.
1868c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1869c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1870c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1871c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1872c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1873c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1874c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1875c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1876c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1877c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1878c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        assertStoredValuesOrderly(filterUri, v1, v2, v3);
1879c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    }
1880c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
188146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
188246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
18838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
18844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
18854928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
1886dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
18878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
18884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
18894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
18904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
18914928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
189246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
189346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
189446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
189546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
189646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
189746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
189846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
189946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
190046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
190146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
190246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
190346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
190446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
190546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
190646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
190746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
190846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
190946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
191046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
191146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
191246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
191346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
191446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
191546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
191646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
191746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
19184928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
191946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1920dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
1921dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId1,
1922dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0
1923dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
1924dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId2,
1925dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 1
1926dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
1927dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
1928dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
1929dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // account3@email.com should be the first.
193046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
193146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
193246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
193346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1934f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1935f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1936f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1937f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1938f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
19398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1940f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1941f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1942f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1943f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1944f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1945f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1946f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1947f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1948f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1949f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1950f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1951f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1952f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1953f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1954f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1955f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1956f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1957f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1958f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1959f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1960f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1961f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1962f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1963f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1964f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1965f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1966f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1967f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1968f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1969f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1970f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1971f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1972f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1973f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1974f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1975f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1976f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1977f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1978f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1979f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1980f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1981f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1982f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1983f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1984f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1985f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1986f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1987f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1988f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1989f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1990f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1991f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1992f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1993f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1994f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1995f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1996f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1997f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1998f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
19994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
20008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Alice", "Nextore");
20014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
20028ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
20034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20048ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
20054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
20064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
20074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
20084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
20094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
20104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
20114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
20124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20138ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
201448828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
201548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
20164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
20178ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20188ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
20198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
20208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
20218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
20228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
20238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
20258ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
20268ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
20278ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20288ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
20298ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
20308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
20318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
20328ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
20338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
20348ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
20358ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20368ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
20378ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20388ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
20398ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
20408ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
20418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
20424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
20434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testDataContentUriInvisibleQuery() {
20458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues values = new ContentValues();
20468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final long contactId = createContact(values, "John", "Doe",
20478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
20488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                        StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
20498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri uri = Data.CONTENT_URI.buildUpon().
20518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true").build();
20528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(4, getCount(uri, null, null));
20538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(contactId);
20558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(uri, null, null));
20578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
20588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesQuery() {
20608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
20618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
20628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
20648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
20658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
20678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
20698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
20708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
20718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
20728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
20748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
20768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
20778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
20788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
20798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri0 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "");
20818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri0, null, null));
20828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
20848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2);
20858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
20878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2);
20888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale@ac");
20908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2);
20918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "510");
20938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv1, cv2);
20948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "cold");
20968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri5, null, null));
20978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
20998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
21008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri6, null, null));
21018f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21028f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Contactables.CONTENT_URI;
21038f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri7, cv1, cv2);
21048f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
21058f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21068f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesMultipleQuery() {
21078f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
21098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
21108f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
21118f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
21128f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "hot@google.com");
21138f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Cold",
21158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamago");
21168f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId2, "eggs@farmers.org");
21178f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
21198f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId3, "518-354-1111");
21208f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId3, "doeadeer@afemaledeer.com");
21218f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21228f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
21238f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21248f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21258f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
21268f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
21278f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
21288f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21298f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
21308f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21318f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21328f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
21338f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
21348f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
21358f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv3 = new ContentValues();
21378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.DATA, "hot@google.com");
21408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.TYPE, Email.TYPE_HOME);
21418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.putNull(Email.LABEL);
21428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv4 = new ContentValues();
21448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Contacts.DISPLAY_NAME, "Cold Tamago");
21458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.DATA, "eggs@farmers.org");
21478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.TYPE, Email.TYPE_HOME);
21488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.putNull(Email.LABEL);
21498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv5 = new ContentValues();
21518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Contacts.DISPLAY_NAME, "John Doe");
21528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.DATA, "doeadeer@afemaledeer.com");
21548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.TYPE, Email.TYPE_HOME);
21558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.putNull(Email.LABEL);
21568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv6 = new ContentValues();
21588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Contacts.DISPLAY_NAME, "John Doe");
21598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.DATA, "518-354-1111");
21618f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.TYPE, Phone.TYPE_HOME);
21628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.putNull(Phone.LABEL);
21638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
21658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2, cv3);
21678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
21698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2, cv3);
21708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tam");
21728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2, cv3, cv4);
21738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "518");
21758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv5, cv6);
21768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doe");
21788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri5, cv5, cv6);
21798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "51");
21818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri6, cv1, cv2, cv3, cv5, cv6);
21828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
21848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
21858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri7, null, null));
21868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri8 = Contactables.CONTENT_URI;
21888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri8, cv1, cv2, cv3, cv4, cv5, cv6);
21898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // test VISIBLE_CONTACTS_ONLY boolean parameter
21918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri9 = filterUri6.buildUpon().appendQueryParameter(
21928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                Contactables.VISIBLE_CONTACTS_ONLY, "true").build();
21938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv1, cv2, cv3, cv5, cv6);
21948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // mark Hot Tamale as invisible - cv1, cv2, and cv3 should no longer be in the cursor
21958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(queryContactId(rawContactId));
21968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv5, cv6);
21978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
21988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
22004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
22014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
22024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2203aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2204d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
22054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
22064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
22084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
22094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
22124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
22134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2214aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2215aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
221682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2217aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
2218ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2219ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2220ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
22214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2223a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
22244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
222548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2226aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2227d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2228aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
222948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
223048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
223148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
223248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
22333b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
22343b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
22358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, nameValues);
223648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
223748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
223882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
223948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2240ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
2241ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
22424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
224348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
22443b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
224548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2246a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
22473b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
22483b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
2249a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
22507ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22517ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
22527ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
22537ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
22547ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22557ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
22567ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22577ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
22587ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
2259a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2260a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2261a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2262a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
2263a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2264a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2265a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2266a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2267a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2268a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2270a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2271a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2272a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2273a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2274a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
2275a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2276a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2277a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
2278a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
2279a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
2280a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
2281a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
2282a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2283a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
2284a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
2285a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2286a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2287a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2288a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
2289a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2290a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2291a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2292a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2293a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2294a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2296a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2297a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2298a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2299a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2300a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
2301a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2302a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2303a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
2304a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
2305a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
2306a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
2307a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2308a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
2309a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
2310a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
23114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
23124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23132f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
23142f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
23152f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
23162f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
2317ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
23184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
23192f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
23202f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
23214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
23222f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
2323d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
23244928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
23254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
23264928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
2327aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
2328aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
23294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
23302f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
23312f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
23322f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
23332f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
2334d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
23354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
23369dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
2337aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
2338d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
23394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23402f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
23412f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
23422f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
23432f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
23454928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
23462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23472f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
23482f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23492f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
23502f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23514928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23522f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
23534928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23542f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23552f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
23562f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
23582f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23599dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
23609dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
23619dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
23622f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
23632f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
23642f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
23659dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
23669dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
23679dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Now the 4th contact has a phone number.
23689dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        insertPhoneNumber(rawContactId4, "18004664414");
23699dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
23709dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Phone only strequent should return 4th contact.
23714928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
23724928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
23734928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
23744928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
23754928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
23764928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
23774928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
23784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2379ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
23802f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
23814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
23824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
238363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testQueryContactStrequentFrequentOrder() {
238463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare test data
23858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContact(mResolver);
238663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1 = ContentUris.parseId(insertPhoneNumber(rid1, "1"));
238763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1e = ContentUris.parseId(insertEmail(rid1, "1@email.com"));
238863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContact(mResolver);
239063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did2 = ContentUris.parseId(insertPhoneNumber(rid2, "2"));
239163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContact(mResolver);
239363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did3 = ContentUris.parseId(insertPhoneNumber(rid3, "3"));
239463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContact(mResolver);
239663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did4 = ContentUris.parseId(insertPhoneNumber(rid4, "4"));
239763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid5 = RawContactUtil.createRawContact(mResolver);
239963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did5 = ContentUris.parseId(insertPhoneNumber(rid5, "5"));
240063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
24018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid6 = RawContactUtil.createRawContact(mResolver);
240263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did6 = ContentUris.parseId(insertPhoneNumber(rid6, "6"));
240363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
240463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid1 = queryContactId(rid1);
240563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid2 = queryContactId(rid2);
240663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid3 = queryContactId(rid3);
240763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid4 = queryContactId(rid4);
240863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid5 = queryContactId(rid5);
240963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid6 = queryContactId(rid6);
241063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Make sure they aren't aggregated.
241263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        EvenMoreAsserts.assertUnique(cid1, cid2, cid3, cid4, cid5, cid6);
241363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare the clock
241563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.install();
241663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // We check the timestamp in SQL, which doesn't know about the MockClock.  So we need to
241863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // use the  actual (roughly) time.
241963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long nowInMillis = System.currentTimeMillis();
242163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
242263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
242363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
242463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // A year ago...
242663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(oneYearAgoInMillis);
242763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1, did2);
242963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1);
243063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // 7 days ago...
243263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(sevenDaysAgoInMillis);
243363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3, did4);
243563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3);
243663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Yesterday...
243863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(yesterdayInMillis);
243963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5, did6);
244163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5);
244263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Contact cid1 again, but it's an email, not a phone call.
244463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1e);
244563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- The regular frequent, which is contact based.
244763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note because we contacted cid1 yesterday, it's been contacted 3 times, so it comes
244863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // first.
244963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
245063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid1),
245163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid5),
245263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid6),
245363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid3),
245463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid4),
245563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid2));
245663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
245763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- phone only frequent, which is data based.
245863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note this is based on data, and only looks at phone numbers, so the order is different
245963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // now.
246063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI.buildUpon()
246163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "1").build(),
246263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did5),
246363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did6),
246463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did3),
246563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did4),
246663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did1),
246763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did2));
246863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
246963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
247045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
247145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
247245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
247345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
247445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
247545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
247645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
247745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
247845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
247945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
248045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
248145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
248245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
248345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
248445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
2485363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
2486363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
248745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
248845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
248945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
249045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
249245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
249445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
249645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
249745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
249845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
250045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
250145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
250245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
250345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
250445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
250545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
250645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
250745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2508363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2509363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
2510363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2511363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2512363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
2513363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2514363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2515363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
2516363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2517363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
2518363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
2519363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
2520363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
2521363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
2522363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2523363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2524363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2525363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2526363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2527363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
252845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
252945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
253080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    public void testQueryContactFrequentExcludingInvisible() {
253180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values1 = new ContentValues();
253280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email1 = "a@acme.com";
253380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
253480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
253580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values2 = new ContentValues();
253680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email2 = "b@acme.com";
253780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid2 = createContact(values2, "Sam", "Times", "18004664412",
253880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
253980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
254080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
254180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
254280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
254380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // First, we have two contacts in frequent.
254480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
254580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
254680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Contact 2 goes invisible.
254780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        markInvisible(cid2);
254880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
254980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Now we have only 1 frequent.
255080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values1});
2551216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2552216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    }
2553216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2554216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    public void testQueryDataUsageStat() {
2555216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        ContentValues values1 = new ContentValues();
2556216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final String email1 = "a@acme.com";
2557216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
2558216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
2559216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2560216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.install();
2561216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(100);
2562216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2563216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2564216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2565216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 1, 100);
2566216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2567216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(111);
2568216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2569216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2570216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 2, 111);
2571216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2572216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(123);
2573216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
2574216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2575216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 3, 123);
2576216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2577216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeLongText = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2578216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_LONG_TEXT).build();
2579216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2580216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeLongText, "a@acme.com", 2, 111);
2581216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2582216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(200);
2583216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2584216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2585216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2586216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2587216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 6, 200);
2588216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2589216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeCall = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2590216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_CALL).build();
2591216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2592216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeCall, "a@acme.com", 3, 200);
259380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    }
259480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
2595ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
25964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
25974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
25984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
25994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
2600aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
2601aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
26024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
26034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
26044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
2605aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
2606aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
26074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2608ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
26094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
26104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
26124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
26134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2615ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
26164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
26174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
26184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2621ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
26224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
26234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
26244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
26263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
262736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
262836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
262924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
263024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
263136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
263236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
263324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
263436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
263524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
263624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
263724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
263824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
263924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
264036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
264136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
264236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
264336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
264436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
264536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
264636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
264736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
264836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
264936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
265036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
265124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
265224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
265336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
265436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
265536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
265636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
265724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
265824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
265936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
266036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
266136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
266236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
266324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
266424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
266524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
266624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
266724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
266824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
266924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
267024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
267124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
267236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
267336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
267436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
267536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
267624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
267724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
267824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
267924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
268024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
268124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
268224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
268336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
268436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
268536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
268636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
268724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
268824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
268924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
269024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
269124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
269224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
269324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
269424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
269524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
269636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
269736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
269836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
269924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
270024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
270136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
270236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
270336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
270436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
270536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
270624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
270724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
270836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
270936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
271036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
271136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
271236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
271324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
271424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
271524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
271624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
271724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
271824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
271924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
272024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
272124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
272224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
272324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
272524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
272636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
272736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
272836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
272936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
273024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
273124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
273324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
273424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
273624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
273736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
273836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
273936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
274036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
274124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
274224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
274424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
274524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
274724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
274824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
275024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
275124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
275224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
275324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
275424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
275524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
275624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
275724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
275824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
275924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
276024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
276124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
276224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
276324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
276424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
276524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
276624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
276724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
27686ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
27696ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
27706ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
27716ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27726ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
27738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Domo", "Arigato");
27746ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
27756ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
27766ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
27776ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
27786ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27796ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
27806ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
27816ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
27826ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
27836ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
27846ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
27856ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27866ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
27876ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
27886ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
27896ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27905d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
279124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
279224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
279324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
279424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
279524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
279624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
279724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
279824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
27995d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
280024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
28015d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
28025d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
280324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
280424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
280624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
280724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
280824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
281024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
281124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
281224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
281424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
281524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
281724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
281824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
281924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
282024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
282124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
282224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
282324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
282424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
282524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
282624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
282724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
282824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
282924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
283024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
283124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
283224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
283324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
283424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
283524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
283624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
283724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
283824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
283924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
284024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
284124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
284224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
284324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
284424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
284524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
284624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
284724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
284824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
284924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
285024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
285224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
285324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
285424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
285624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
285724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
285924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
286024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
286124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
286324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
286424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
286524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
286724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
286824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
286924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
287024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
287224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
287324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
287424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
287624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
287724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
287824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
287924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
288024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
288224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
288324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
288524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
288624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
288724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
288824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
289024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
289124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
289224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
289324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
289424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
289524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
289624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
289724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
289824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
289924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
290024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
290124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
290224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
290324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
2904cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
2905cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
2906cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
2907cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
2908cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
2909cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
2910cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
2911cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2912cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
2913cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
2914cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2915a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
2916a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
2917a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
2918a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2919a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
2920a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
2921a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
29228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri profileUri = TestUtil.maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI,
29238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account)
2924a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
2925a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
2926a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
2927a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
2928a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2929a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
2930a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
2931a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
2932a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
293385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
293485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
293585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
293687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
293785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
293885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
293985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
294085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
294185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
294285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
294385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
294487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
294585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
294685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
294785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
294885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
29490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
295019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
295119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
295219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
295319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
29548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
295519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
295619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
295719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
295819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
295919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
296019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
296119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
296282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
2963aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
2964aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
296582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
2966aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
2967aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
296819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
296919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
297082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
297119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
2972a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
2973a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
297419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
297519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
297619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
297719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
297819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
297982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
29800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
298119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
298219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
298319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2984a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
298519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
298619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
298719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
298819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
298919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
299082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
29910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
299219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
299319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
299419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2995a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
299619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
299719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
299819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
299919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
300019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
300189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
300289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
300389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
300489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
300589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
30068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
30078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
300889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
300989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
301089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
301189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
301289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
301389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
30143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
30153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
30163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30173cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
30183cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
30199d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
30203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
30213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
30223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
30233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
30243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
30253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
30263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
30273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
302894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
30293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
30303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
30313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
30323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
30333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30343cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
30353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
303673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
30373cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
30383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
30393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
3040f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
30418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3042f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3043f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3044f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
3045f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3046f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
3047f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3048f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3049f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
30508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3051f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3052f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3053f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3054f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
3055f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3056f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
3057f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3058f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3059f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
30608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3061f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3062f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3063f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
3064f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
3065f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
3066f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
3067f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
3068f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
3069f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
3070f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
3071f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
3072f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
3073f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
3074f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3075f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
30765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
30775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
30785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
30795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
30815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
30825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
30835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
30855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
30865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
30875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
30885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
30905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
30915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
30925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
30945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
30955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
30965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
30985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
30995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
31005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
31025f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
31035f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31045f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
31055f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
31065f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
31075f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31085f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
31095f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
31105f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
31115f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31125f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
31135f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
31145f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
31155f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
31165f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
31175f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
31185f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
31195f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31205f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
31215f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
31225f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
31235f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31245f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
31255f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
31265f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
31275f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31285f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
31295f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
31305f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
31315f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31325f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
31335f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
31345f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
3135f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
3136f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
3137f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
3138f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
3139f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
3140f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
3141f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3142f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
3143f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
31448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId0 = RawContactUtil.createRawContactWithName(mResolver, "firstName0",
31458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName0");
3146f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
31478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "firstName1",
31488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName1");
3149f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
3150f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
3151f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
31528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "firstName2",
31538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName2");
3154f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
3155f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
3156f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
3157f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3158f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
3159f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
3160f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
3161f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
3162f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
3163f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
3164f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
3165f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
3166f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3167f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
3168f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
3169f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
3170f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
3171f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
3172f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
3173f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
3174f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
3175f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3176f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
3177f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
3178f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
3179f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
3180f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
3181f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
3182f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
3183f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
3184f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3185f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3186f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3187f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
3188f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
3189f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
3190f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
3191f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3192f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3193f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3194f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
31958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "firstName3",
31968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName3");
3197f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
3198f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
3199f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
3200f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
3201f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3202f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3203f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3204f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
320518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
320618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
320718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
320818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
320918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
321018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
321118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
321218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
321318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
321418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
321518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
321618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3217f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
3218f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3219f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
3220f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
3221f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
322218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
322318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
322418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
322518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
322618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
322718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3228f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
3229f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
3230f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
3231f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
3232f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
3233f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
3234f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
3235f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
323618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
323718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
323818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
323918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
324018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
324118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3242f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
324323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
324423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
324523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
324623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
324723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
324823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
324923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
325023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
325123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
325223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
325323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
325423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
3255f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3256f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
325789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
325889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
325989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
3260f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
326189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
326289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
3263f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
32648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
32658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
3266f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
3267f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
3268f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
3269f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
3270f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
327189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
327289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
3273f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
327489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
3275f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
327689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
3277f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
3278f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
3279f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
3280f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
3281f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
3282f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
3283f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
3284f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
3285f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
3286f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
3287f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
32880e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
32890e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
32900e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
32910e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
32920e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
32930e21a867a572679d64d79041eb574d13665178d4Dave Santoro
32940e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
32950e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
32960e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
32970e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
32980e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
329989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
330089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
33014097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
33028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
33034097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
33044097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
33058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
33064097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
330717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
33084097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
33094097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
331067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
33118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
331267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
331367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
331467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
331567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
33168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
331717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
331867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
331967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
33204097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
33218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
33224097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
33234097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
33244097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
33258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
33264097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
33284097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
33294097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
3331a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.ENGLISH);
33328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, null);
33335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
33355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
33365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
33375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
33385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
33395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
33408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
33415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
334455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
334555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
33465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
33475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
33485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3349a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
33505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3351a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
33545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
33555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
335855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
335955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
33605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
33615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
33625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3363a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
33645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3365a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
33685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
33695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
33705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
33725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
33735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
33745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
3376a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
33775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
33785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
3379a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
33805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
33825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
3384a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        // "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B"
33855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
33868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
33875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
33905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
33915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
33925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
33935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3394a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3395a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3396a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3397a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
34005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
34015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
34055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
34065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
34075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3408a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3409a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3410a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3411a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34210f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    public void testJapaneseNameContactInEnglishLocale() {
34220f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // Need Japanese locale data for transliteration
34230f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        if (!hasJapaneseCollator()) {
34240f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            return;
34250f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        }
34260f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContactLocaleUtils.setLocale(Locale.US);
3427ef5fa9a68690d19e2a9c9748d63e2cabb5075813Jay Shrauner        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
34280f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34290f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContentValues values = new ContentValues();
34300f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
34310f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
34329aec6b8422f8d153a91a241f1b10d6e48d338bb8Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
34330f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34340f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
34350f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // en_US should behave same as ja_JP (match on Hiragana and Romaji
34360f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // but not Pinyin)
34370f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
34380f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
34390f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
34400f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    }
34410f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
3443a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3444a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3445a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3446a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
34478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
34485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
34505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
34515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
34528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
34535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
34575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
34585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
34595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
34605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
34615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3462a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3463a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
34645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
34665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
34675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
34715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
34725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
34735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
34745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
34755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3476a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3477a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
34785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34850f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34860f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
34870f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // ja_JP should match on Hiragana and Romaji but not Pinyin
34880f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
34890f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
34900f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
34915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
349325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
34948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
349525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
349625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
34978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
349825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
349925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
35000c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
35010c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
350225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
350325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
350425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
35058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Potato", "Head");
350625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
350725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
350881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
350925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
351025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
351101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
35128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
351301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3514a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
351501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
351601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
351701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
351801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
351901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
352001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
352101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
352201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
352301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
352401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
352501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
352601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
352701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3528a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
3529a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3530a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
35315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
353201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
353301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3534a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
3535a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
3536a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
3537a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
3538a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
3539a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3540a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
3541a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
3542a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
35438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
35445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
35455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
35488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
35495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
35505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
35515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
35535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
35555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
35575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
35585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
35595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
35615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
35635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
35645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
35675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
35685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
35695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
35705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
3571a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "M");
3572a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "M");
35735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
35745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
3577a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3578a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3579a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3580a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
35818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
35825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
35835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
35845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
35865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
35885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
35905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
35915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
35925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
35955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
35965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
35975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
35985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
3599a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u305F");
3600a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u305F");
36015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
36025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
36035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
3605a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
36060b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
36070b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
3608a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
36090b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
36108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
36115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
36125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
36135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
36155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
36175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
36195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
36205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
36235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
36245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3625a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u4E2D\u56FD\u7535\u4FE1");
3626a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "Z");
3627a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u4E2D\u56FD\u7535\u4FE1");
3628a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "Z");
36295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
363001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
363101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
363231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
36338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
363431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
363531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
363631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
363731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
363831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
363931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
364031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
364131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
364331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
364431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
364631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
364731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
364831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
365031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
365131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
365231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
365331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
365431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
365531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
365631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
365731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
365831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
365931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
366031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
366131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
366231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
366331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
366431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
366531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
366631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
366731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
366831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
366931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
367031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
367131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
367231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
367331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
367431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
367531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
367631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
367731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
367831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
367931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
3680a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
36810f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
36820f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertEquals(0, getCount(filterUri, null, null));
3683a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
3684a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
3685916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
36868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3687916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3688916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3689916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
3690916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
3691916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3692916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3693916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3694916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
36959c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
3696916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
3697916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3698916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
3699916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
3700916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3701916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3702916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
3703916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
3704916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3705916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3706916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
3707916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3708916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37096f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3710916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3711916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3712916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37136fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "acmecorp");
37146fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(filterUri, values);
3715916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3716916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3717916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
37188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
3719916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3720916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3721916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
3723916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3724916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37256f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3726916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3727916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3728916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37296fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "acme@corp.com");
3730916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3731916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3732916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3733fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
3734fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
3735fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
3736fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
3737fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
3738fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
3739fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
3740fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
3741fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
3742fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
3743fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
3744fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
3745fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
37463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
37478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
37483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
37493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
37503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
37523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
37533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
37553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
37563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
37573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
37603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
37623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
37643716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
37663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37673716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
37683716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37693716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
37703716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37713716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
37723716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
37733716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37746f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
37756f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
37766f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
37776f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
37786f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
37796f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
37806f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
37816f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
37826f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
37836fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    public ContentValues createSnippetContentValues(long contactId, String snippet) {
37846fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        final ContentValues values = new ContentValues();
37856fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.clear();
37866fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(Contacts._ID, contactId);
37876fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, snippet);
37886fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        return values;
37896fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    }
37906fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng
3791916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
37928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3793916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3794916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3795916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3796916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
3797916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37986f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
3799916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3800916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3801916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
38026fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(SearchSnippetColumns.SNIPPET, "Incredible");
3803916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3804916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3805916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
38063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
38078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
38103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38126fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
38133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38146fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
38156fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("john", true), snippet);
38163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
38198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
38223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38246fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
38253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38266fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
38273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
38308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
38333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
38343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
38353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
38363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
38373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
38383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38396fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "aperturepresident");
38403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38416fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("aperture", true), snippet);
38423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
38458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
38483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
38493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38506fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "860-555-1234");
38513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38526fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("860", true), snippet);
38533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
38568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
38603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38616fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId,
38626fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng                "Cave Johnson is president of Aperture Science");
38633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38646fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
38653716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38663716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
3867dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
38688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, "Slinky", "Dog");
3870dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3871dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3872dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3873dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3874dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
3875dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3876dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
3877dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
3878dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3879dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3880dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
3881dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3882dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
3883dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3884dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3885dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
3886dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3887dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
3888dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3889dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3890dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
3891dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
3892dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3893d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
3894d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
3895d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
3896d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3897d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
3898d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
3899d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
3900d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
3901d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
3902d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3903d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
3904d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
3905d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
3906d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3907d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
3908d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
3909d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
3910d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
39118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3912d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3913d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3914d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3915d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3916d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3917d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
3918d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3919d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3920d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3921d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
39228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3923d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3924d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3925d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
3926d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
392781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
39288c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
39298c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
39308c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
39318c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
3932d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3933d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3934d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
39358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "a", "b");
3936d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3937d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3938d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "c", "d");
3940d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3941d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
3942d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3943d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39440c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39450c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3946d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3947d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
3948d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
3949d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3950d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3951d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
39528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "e", "f");
3953d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3954d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
3955d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "g", "h");
3957d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3958d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
3959d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3960d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39610c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39620c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3963d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3964d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
39650c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
3966d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3967d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3968d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
39698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "i", "j");
3970d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3971d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3972d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "k", "l");
3974d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3975d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
3976d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3977d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39780c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39790c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3980d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3981d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
39820c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
39830c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3984d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
3986d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
3987d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3988d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
398982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
39908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
39910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
39920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
39930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
39940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
39950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
39960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
39970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
39980a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
39990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
40000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
40020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
40030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
40040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
40050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
40070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
40090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
40110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
40120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
40160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
40170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
40180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
40190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
40200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
40260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
40270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
40280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
40290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
40300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
40310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
40350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
40360a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
40370a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
40380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
40390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
40410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
40438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40440a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
40450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
40460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
40480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
40500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
40510a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40530a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
40540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40560a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40570a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
40580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
40610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
40620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
40648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40654dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
40664dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
406782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
40684dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40694dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
4070aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4071aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
40724dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40734dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
4074aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
4075d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
40764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40774dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
4078aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
4079aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
40804dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40814dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
4082aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
4083aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
40844dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
408582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
408682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
40870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
408882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
40894dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
409082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
40914dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
409282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
40934dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
409482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
40954dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
40964dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
4097bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4098bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4099bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4100bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4101bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
410282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
41030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4104bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4105bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
4106bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
410782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
41088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4109bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4110bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4111bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4112bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4113bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4114bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
411582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
411682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
4117bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4118bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4119aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
4120aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4121aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
4122aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
412382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
4124aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4125aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
412682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4127bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
412882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
412982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4130bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4131bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
41329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
41339705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
41349705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
41359705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
41369705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
41379705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
41389705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
41399705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41409705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41419705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
41439705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41449705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41459705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41469705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41479705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
41489705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
41499705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
41509705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
41519705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
41529705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41539705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41549705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41559705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41569705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41579705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
41589705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
41599705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41609705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41619705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
41629705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
41639705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
41649705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41659705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
41669705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41679705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41689705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
41699705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41709705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41719705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41729705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41739705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
41749705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
41759705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
417682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
41779705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
417882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4179a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4180a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
4181a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4182093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
41838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4184093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4185093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4186093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4187093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4188093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4189093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
4190093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
4191093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4192093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
4193093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4194093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4195093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
4196093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4197093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4198093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4199093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4200093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
4201093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
4202093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
4203093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4204093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4205093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4206093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4207093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4208093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
4209093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
421082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
42118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4212a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4213a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
4214a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4215a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4216a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4217aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
42185d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4219aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
42205d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4221aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
42225d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4223a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4224a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
4225a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
422682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
422782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4228bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
42294dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42304dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
423182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
423282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
42334dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
423482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
423582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
4236a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
423782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
42384dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
42394dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42404dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
42413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
42423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
42448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
42453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
42473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
42503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
42513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
42558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
42623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
42678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
42703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
42753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
42808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
42833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
42883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
42893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
42903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
42958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
42993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
43028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
43053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
43093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
43133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
43173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
43208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
43323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
43333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
43363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
43373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
43403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
43428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
43453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
43463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
43483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
43496802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
43513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
43523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
43543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
43553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
43563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
43598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
43623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
43673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
43723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
43733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
43746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
43773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
43786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
43796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
43803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
43816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
43843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
43853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
43863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
43873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
43908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
43933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
43983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
44003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
44013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
44033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
44043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
44053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
44066802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
44093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
44106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
44116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
44123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
44133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
44146802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
44173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
44203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
44223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
44233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
44253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
44283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
44303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
44313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
44343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
44363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
44373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
44393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
44413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
44433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
44443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
44463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
44473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
44483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
44493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
44503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
44513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
44523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
44568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
44593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
44603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
44613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
44623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
44633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
44668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
44693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
44713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
44733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
44743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
44753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
44763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
44773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
44783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
44803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
44823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
44833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
44853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
44863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
44873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
44883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
44893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
44903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
44913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
44923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
44933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
44943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
44973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
44983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
45018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
45043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
45063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
45073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
45093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
45113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
45123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
45153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
45163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
45173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
45193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
45223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
45248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
45263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
45273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
45293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
45303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
45313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
45333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
45343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
45363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
45373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
45383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
45393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
45403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
45423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
45443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
45453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
45463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
45473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
45483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
45503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
45513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
45523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
45533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
45543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
45573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
45586802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
45596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
45603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
45613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
45636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
45646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
45656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
45666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
456787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                EvenMoreAsserts.assertImageRawData(getContext(),
4568c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                        expectedPhotoBytes, mResolver.openInputStream(Uri.parse(photoUri)));
45696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
45703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
45713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
45723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
45763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
45788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
45813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
45823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
45833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
45843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
45853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
45863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
45883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
45918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
45943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
45953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
45963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
45973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
45983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
45993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
46013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
46043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46056802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
46068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46146802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46156802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
46173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
46183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
46193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
46213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
46223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
46236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
46243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
46256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
46266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
46276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
462887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4629c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
46306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
46313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
46348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
46436802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46446802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
46463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
46473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
46493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
46506802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
46513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
46526802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
46536802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
46546802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
465587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4656c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
46576802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
46583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
46613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
46638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
46653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
46663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
46673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
46693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
46703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
46713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
46733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
46743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
46753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
46773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
46803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
46838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
46853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
46863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
46883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
46893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
46903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
46923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
46933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
46943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
46963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
46993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
47023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
47048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
47083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
47093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
47103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
47113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
47123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
47143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
47153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
47173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
47183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
47193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
47203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
47213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
47223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
47233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
47243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
47253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
47288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
47323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
47333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
47346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
47353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
47363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
47373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
47393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
47403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
47423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
474482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
47458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
474682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
474782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
474882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
474982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
475082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
475182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
475282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
475382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
475482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
475582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
475682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
475782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
475882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
475982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
47603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
47613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
47623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
47633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
47643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
47676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
47686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
47706802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
47726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
47736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
47746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
47756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
47766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
47776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
47786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
47806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
47814747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
4782d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
4783d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
4784d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
4785d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
4786d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
4787d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4788d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
4789d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4790d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
4791d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
4792d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
4793d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
4794d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
4795d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
4796d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4797d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
4798d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
4799d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
4800d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4801d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
4802d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48034747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
48046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48056802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48066802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48076802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48086802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48096802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
48116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
48136802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
48146802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
48156802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
48166802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
48176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
48186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
48196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
48216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
48226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
48236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
48256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48264747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
48276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
483336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
48348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
483536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
483636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
483736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
483836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
483936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
484036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
484136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
484236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
484336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
484436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
484536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
484636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
484736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
484836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
484936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
485036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
485136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
485236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
485336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
485436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
485536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
485636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
485736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
485836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
485936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
486036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
486136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
486236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
486336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
486436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
486536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
486636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
486736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
486836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
486936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
487036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
487136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
487236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
487336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
487436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
487536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
487636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
487736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
487836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
487936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
488036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
488136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
488236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
488336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
488436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
488536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
48868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
488736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
488836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
488936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
489036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
489136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
489236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
489336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
489436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
489536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
489636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
489736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
489836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
489936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
490036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
490136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
490236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
490336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
490436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
490536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
490636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
490736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
490836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
490936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
49108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
491136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
491236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
491336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
491436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
491536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
491636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
491736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
491836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
491936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
492036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
492136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
492236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
492336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
492436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
492536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
492636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
492736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
492836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
492936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
493036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
493136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
493236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
493336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
493436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
493536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
493636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
493736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
493836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
49398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
494036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
494136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
494236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
494336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
494436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
494536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
494636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
494736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
494836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
494936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
495036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
495136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
495236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
495336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
495436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
495536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
495636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
495736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
495836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
495936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
496036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
496136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
496236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
496336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
496436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
496536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
496636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
496736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
496836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
496936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
497036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
497136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
497236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
497336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
497436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
497536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
49768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
497736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
497836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
497936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
498036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
498236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
498336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
498536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
498736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
498836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
498936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
499036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
499136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
499236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
49933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
49943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
49953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
49963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
49973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
49983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
49993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
50023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
50033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
50046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
50056802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
50063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
50073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
500982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
5010bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
5011bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
5012bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
50138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
50144dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
5015bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5016aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
5017aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5018aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
5019aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5020aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
5021aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5022bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5023af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
502482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
50254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
5026bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5027bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
502882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
502982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
50300265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
5031bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
5032bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5033d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
5034d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
5035d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
5036d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
5037d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
5038d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
5039d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5040d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5041d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5042d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
5043d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
50448c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
50458c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
50468c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
50478c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
50488c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
50498c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
50508c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
50518c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
50528c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
50538c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
50548c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
50558c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
50568c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
5057d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
5058d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5059d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
5060d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
5061d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
5062d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
5063d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
5064d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
5065d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
5066d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
5067d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
5068d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
5069d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
5070d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5071d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
5072d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
50739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
50740be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
50758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
50760be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
50770be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50780be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
50790be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
50800be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50810be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
50820be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50830be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50840be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
50850be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50860be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50870be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
50880be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
50890be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50900be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
50910be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
50920be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50930be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
50940be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50950be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
50960be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50970be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
50980be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
50990be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
51000be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
51010be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
51020db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
51030db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
51040db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
51050db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
51060db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
51070db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
51080db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
51090db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51100db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
51110db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
51120db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51130db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
51140db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
51150db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51160db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51170db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51180db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51190db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
51200db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
51210db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51220db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
51230db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
51240db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51250db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51260db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
51270db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51280db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
51290db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
51300db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
51310db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
51320db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
51330db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
5134a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
51359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
51369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
51379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51389261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
51399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
51409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID, "c0");
51423cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
51433cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
51443cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
51459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c1 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c1");
51489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
51499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
51509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
51519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
51529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c2 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c2");
51559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
51569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
51579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
51589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c3 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c3");
51619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
51629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
51639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
51649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
516562318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
51668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount),
51678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                null, RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
51689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
51699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
51709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
51716cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
51729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
51739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
51749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
51759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
51769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
51779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
51789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
51799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
51809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
51819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
51829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
51839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
51849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
51859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
51869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
51879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
51889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
51906cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
51919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
51929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
51939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
51949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
51959261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
51969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
51979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
51989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
51999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
52009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
52019261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
52029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
52039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
52056cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
52069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
52079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
52089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
52099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
52109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
52119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
52129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
52139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
52149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
52159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
52169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
52179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
52189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
52203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
52219261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
522220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
522320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
52248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
522520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
522620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
52275ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
522820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
522920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
523020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
523120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
523220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
523320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
523420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
523520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
523620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
523720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
523820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
523920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
524020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
524120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
524220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
524320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
524420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
524520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
524620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
524720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
524820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
524981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
525020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
525120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
525220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
525320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
525420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
525520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
525620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
525720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
525820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
525920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
526020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
526120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
526220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
526320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
526420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
526520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
526620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
526720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
526820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
526920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
52705ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
527120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
527281d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
527370b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
527420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
527520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
52765ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
527720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
527820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
52795ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
528033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
528181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
528233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
528320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
528489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
528589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
528689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
52878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
52888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
528989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
52908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
52918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
529289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
529389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
529489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
529589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
529689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
529789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
529889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
529989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
530089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
530189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
530289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
5303373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
53048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
53055ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
530633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53074dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
530882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5309aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5310aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5311a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
5312a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
531333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
531433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
531582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53164dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
531733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
531833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
531933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53205870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
532181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
532233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
5323e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
532433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
532533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
532633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
532733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
532882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53294dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
5330a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
533181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
5332a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
5333a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5334a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
53358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
53368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
533747fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
533847fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
5339a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5340a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5341a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5342a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
5343e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
5344a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
5345a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
5346a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
534720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
53481fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
53495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
53508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5351e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
5352e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5353e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
535482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5355aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5356aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5357e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
5358e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
535982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
5360e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
5361e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5362e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
5363e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
5364e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5365e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
5366e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
5367e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
53685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
53695f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
5370e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
53715870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
5372e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5373e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
5374e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
5375e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5376e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
5377e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
5378e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
53795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
53805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
53815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
53835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
53845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
53868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
53875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
53885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
53905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
53915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
53925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
53935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
53945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
53965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
53985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
53995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
54005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
54015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
5402e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54035870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
5404e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
5405e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
54079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
54089ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
54099ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
54109ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
54119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
54128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2);
54159ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54169ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
54178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1);
54209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
54229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
54239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
54249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
54279ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
54289ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
54299ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54309ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
54429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
54439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
54449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
54459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
54469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
54479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
54499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
54509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
54519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
54539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
54549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
54559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
54569ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
54579ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
54589ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54599ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
54608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1 = new Account[] {TestUtil.ACCOUNT_1};
54618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2 = new Account[] {TestUtil.ACCOUNT_2};
54628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1_2 = new Account[] {TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2};
54638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2_1 = new Account[] {TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1};
54649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
54669ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54679ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
54689ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
54699ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
54709ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54719ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
54729ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54739ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
54749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
54759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
54769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
54779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
54789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
54799ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
54809ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54819ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
54829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
54849ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
54859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
54869ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
54889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
54909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
54919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
54929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
54949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
54969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
54979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
54999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
55009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
55019ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
55029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
5503627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
550470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
550570d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
55068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
550770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
5508627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
5509743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
551070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
551170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5512bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
5513743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
5514743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
5515dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
5516dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
551770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
55188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
5519743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
55208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
5521743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
5522743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
5523743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5524aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5525aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5526743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
5527bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
5528743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
5529627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
553082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
553170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
553270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
553370d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
553433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
553533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
553633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5537bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
553833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
553933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
55408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
55418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                readOnlyAccount);
554233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
55438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "john", "doe",
55448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                mAccount);
554533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
554633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
554733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
554833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
554933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
555033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
555133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
555233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
555333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
555433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
555533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
555633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
555733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
555833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
555933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
556033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
556133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5562bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
556333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
556433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
556533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
556633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
556733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
556833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
556933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
557033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
557133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
557233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
557333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
557433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
557533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
557633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5577c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
5578c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
5579c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
5580c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5581c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
5582c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
5583c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5584c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
55858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long doomedRawContactId = RawContactUtil.createRawContactWithName(mResolver, doomedAccount);
5586c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
5587c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
5588c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
5589c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
5590c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
5591c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5592c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
55938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long safeRawContactId = RawContactUtil.createRawContactWithName(mResolver, safeAccount);
5594c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
5595c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
5596c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
5597c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
5598c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
5599c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
5600c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5601c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
5602c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
5603c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
5604c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5605c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
5606c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
5607c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
5608c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
5609c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
5610c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
5611c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5612c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
5613c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
5614c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
5615c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
5616c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
5617c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
5618c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5619cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
56208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
56228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
5624cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5625cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5626cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5627cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
5628cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5629cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
5630cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5631cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
5632cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5633cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
5634cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
563573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
56368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
563773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
563873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
56398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
564073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
5641e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
564273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
564373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
564473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
564573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
56465870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
564773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
564881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
56491fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
56501fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
565161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
56528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5653d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
565473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
56551fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
56561fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
56571fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
56581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
56591fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
566061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
5661c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
566261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
56631fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
56641fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
56651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
56661fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
566781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
56681fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
566961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
567061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
567181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56721fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56731fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
567461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
56751fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
567661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
567761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
567861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
56791fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
568081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56811fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56821fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
568361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
56841fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
568561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
56861fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
568781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56881fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56891fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
569061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
56911fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
569261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
56938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
569461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
569561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
569661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
569761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
56981fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
569961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
57001fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57011fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
57021fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
57031fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
57041fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57051fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57061fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
570761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
57088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
57091fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
571061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
57111fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
571261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
571361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
571461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
571561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
57165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
571761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
571881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
571961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
572061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
57211fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
57239fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
57249fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57259fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57269fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57279fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
57289fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57299fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57309fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57319fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57329fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57339fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
57349fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
57359fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
57369fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57379fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
57389fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57399fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57409fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57419fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57429fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57439fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57449fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57459fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
57469fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
57479fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
57489fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
574960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
575060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
575160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
575260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
575360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
575460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
575560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
575660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
575760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
575860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
575960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
576060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
576160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
576260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
576360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
576460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
576560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
576660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
576760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
576860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
576960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
577060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
577160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
577260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
577360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
577460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
5775074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
5776074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
5777074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
5778074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
57798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
5780f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5781f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5782f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
5783f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
5784f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5785074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
57863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
57873d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
5788f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
5789074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
5790074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
5791bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
57928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5793bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
5794bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5795bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
5796bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
5797bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5798bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
5799bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5800bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
5801bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
5802bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5803bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
5804bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5805bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
5806bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
5807bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
5808bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
5809bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
5810bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5811bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
581287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5813c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithId));
581487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5815c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
5816bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
5817bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5818ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
58198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5820f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5821f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5822f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
5823f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
5824f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
5825e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
582687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Check the thumbnail.
582787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
5828f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
582987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki
583087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Then check the display photo.  Note because we only inserted a small photo, but not a
583187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // display photo, this returns the thumbnail image itself, which was compressed at
583287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // the thumnail compression rate, which is why we compare to
583387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL) rather than loadTestPhoto(PhotoSize.DISPLAY_PHOTO)
583487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // here.
583587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // (In other words, loadTestPhoto(PhotoSize.DISPLAY_PHOTO) returns the same photo as
583687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL), except it's compressed at a lower compression rate.)
583787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
583887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                mResolver.openInputStream(photoUri));
5839ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
5840ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
5841732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
58428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
5843f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
5844732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
5845732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
58468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
5847f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
5848732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
5849732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5850732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5851732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5852732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5853732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5854732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5855f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5856f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5857f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
5858f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
5859f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5860732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5861f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
5862732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5863732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
5864732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5865732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5866732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
5867732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
5868732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
5869732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5870732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5871732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5872732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5873732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5874732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
5875732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5876732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
5877732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5878732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
5879732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
58808e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
58818e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
58828e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
58838e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
58848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
58858e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58868e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
58878e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
58888e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58898e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
58908e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
58918e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
58928e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
58938e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
58948e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
58958e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5896155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
58978e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58988e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
58998e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
59008e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
590181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
59028e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5903f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
59048e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
59058e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
59068e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59074e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
59087d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
59097d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
59107d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
59117d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
59127d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59137d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
59147d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
59157d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59167d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
59177d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59187d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
59197d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
59207d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
59217d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
59227d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59237d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59247d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59257d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
59267d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59277d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
59287d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
59297d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59307d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
59317d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59327d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59337d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59347d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
59354e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
59367d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
59374e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
5938f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
59390265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
59407d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
59417d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
5942f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
59438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5944f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5945f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5946f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
5947f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5948f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
594987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5950f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5951f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5952f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5953f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5954f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
59558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5956f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5957f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5958f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5959f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5960f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5961f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
596287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5963f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5964f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5965f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5966f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5967f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
59688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5969f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5970f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5971f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5972f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5973f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5974f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5975f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
597687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5977f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5978f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5979f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5980f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5981f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
59828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5983f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5984f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
5985f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5986f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
598787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5988f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5989f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5990f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5991f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5992f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
59938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5994f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5995f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5996f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5997f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
5998f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5999f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6000f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
600187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6002f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6003f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6004f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6005f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6006f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
60078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6008f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6009f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6010f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
6011f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6012f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6013f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
6014f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6015f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6016f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6017f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6018f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
6019f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6020f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6021f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6022f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
6023f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6024f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
6025f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
6026f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6027f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6028f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6029f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
60308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6031f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6032f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6033f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
6034f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
6035f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
6036f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6037f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6038f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6039f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6040f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
6041f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6042f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6043f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6044f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6045f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6046f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
6047f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
6048f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6049f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
6050f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6051f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6052f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
605387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6054f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6055f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6056f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6057f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6058c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
60598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6060f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6061f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6062f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6063c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
6064c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
6065f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6066f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6067c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6068f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6069f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6070c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6071f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6072f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
6073c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
6074c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
6075c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
6076c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
6077c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
6078c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6079c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
6080c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
6081c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6082f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
6083f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6084f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6085f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6086f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
6087c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
6088f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6089f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
609087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6091f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6092f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
609387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6094f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6095f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
6096f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6097f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6098c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
60998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6100f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6101f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6102f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
6103f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
6104f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
6105f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6107f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6108f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
6109f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6110f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6111f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6112f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6113f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6114c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6115c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6116c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
6117c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
6118f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6119f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
6120f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
6121f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6122f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
6123f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6124f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
6125f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
6126f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6127f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
612887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6129f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6130f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
613187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6132f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6133f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
6134f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6135f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6136f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6137c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
6138c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
6139c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
6140c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
6141c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
6142c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
6143c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
6144c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
6145c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
6146c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
6147c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
6148c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
6149c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
6150c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
6151c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
6152c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
6153c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
6154c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
6156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6157f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
6158f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
6159f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
6160f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6161f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6162f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
6163f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6164c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
6165f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6166f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6167f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6168f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6169f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
61708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
6171f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
6172f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
6173f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
6174f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
6175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
61778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
6178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
6179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
6180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
6181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6182f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6184f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
6185f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6186f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
6187f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6188f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
6189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
6190f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
6191f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
6192f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6193f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6195f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
6196f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
61978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver);
6198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
6199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
6200f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
6201f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6202f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
6203f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
6204f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
6205f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
6206f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
6207f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6208c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
6209c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
6210c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
62118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId4 = RawContactUtil.createRawContactWithName(mResolver, socialAccount);
6212c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
6213c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
6214c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6215c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6216c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6217c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6218c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6219c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
6220c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
6222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
6223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
6224f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
6226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6227f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
6229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
6231f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
6232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
6233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
6236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
6237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
6238f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
6240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
6242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
6243f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
6244f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6245f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6246f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
6247f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
6248c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6249c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
6250c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6251c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6252c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6253c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
6254f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6255f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6256d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
6257d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6258d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
6259d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6260d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6261ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6262d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6263d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6264d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
6265d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
6266d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
6267d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
6268d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
6269d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
6270d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
6271d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
6272d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
6273d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
6274d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6275d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
6276d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6277d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
6278d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
6279d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
6280d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
6281d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6282d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6283d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6284d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6285d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6286d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6287d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
6288d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
6289d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
6290d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6291d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
6292ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6293d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6294d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6295d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
6296d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6297d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
6298d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6299d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6300d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6301d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
6302d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6303d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
6304d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
6305d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
6306d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
6307d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6308d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
6309d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6310f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
63118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6312f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6313f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6314f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6315f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
6316f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6317f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
6318f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
6319f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6320f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
6321f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
6322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
6323f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
6324f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6325f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
6326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
6327f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
6328f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
6329f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
6330f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6331f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6332f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
633387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6334c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6335f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6336f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6337f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
63384e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
63398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
63404e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
63418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
63424e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
634347fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
634447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
63454e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63464e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
63474e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
63484e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
63494e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63504e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
63514e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
63524e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63534e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
63544e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63554e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
63564e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
63574e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
63584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63594e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
63604e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
63614e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63624e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
63634e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
63644e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
63654e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63664e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
63674e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
63684e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63694e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
63704e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
63714e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
63724e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
63734e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
63758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
63766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
63776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
63786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
63806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
63816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
63826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
63846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
63856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
63866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
63876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
63886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
63896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
63906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
63916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
63936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
63946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
63956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
63966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
63976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
63986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
63996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
64016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
64026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
64056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
64066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
64146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
64156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
64186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
64196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
64316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
64346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
64356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
64436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
64466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
64476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
64556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
64586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
64596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
64696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
64706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
64726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
64736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
64746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
64756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
64768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
64776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
64786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
64806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
64816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
64826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
64836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
64866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
64876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
64896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
64906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
64916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
64926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
64946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
64956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
64966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
64976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
64996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
65006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
65016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
65026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
65036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
65046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
65076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
65086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
65096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
65106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
65116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
65126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
65156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
65166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
65196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
65206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
65236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
65246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
65276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
65286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
6530a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    public void testContactSortOrder() {
6531a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + ", "
6532a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY,
6533a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY));
6534a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + ", "
6535a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_ALTERNATIVE,
6536a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE));
6537a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + " DESC, "
6538a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY + " DESC",
6539a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY + " DESC"));
6540a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        String suffix = " COLLATE LOCALIZED DESC";
6541a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + suffix
6542a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + ", " + Contacts.SORT_KEY_ALTERNATIVE + suffix,
6543a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE
6544a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                                                             + suffix));
6545a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
6546a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
6547ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
6548ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
6549ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
6550ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
65518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContact(mResolver);
65528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
65538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "The Abominable", "Snowman");
65548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mike", "Wazowski");
65558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "randall", "boggs");
65568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Boo", null);
65578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mary", null);
65588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Roz", null);
6559ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6560ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
6561ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6562a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                null, null, Contacts.SORT_KEY_PRIMARY);
6563ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
656435997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "", "B", "J", "M", "R", "T");
6565ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
6566ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6567ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6568ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
6569ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6570ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
6571ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
657235997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", "");
6573ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
6574ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6575ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6576ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
65771f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    public void testContactCountsWithGermanNames() {
65781f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        if (!hasGermanCollator()) {
65791f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            return;
65801f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
65811f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        ContactLocaleUtils.setLocale(Locale.GERMANY);
65821f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65831f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Uri uri = Contacts.CONTENT_URI.buildUpon()
65841f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
65851f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Josef", "Sacher");
65878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Franz", "Schiller");
65888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Eckart", "Steiff");
65898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Klaus", "Seiler");
65908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Lars", "Sultan");
65918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Heidi", "Rilke");
65928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Suse", "Thomas");
65931f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65941f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Cursor cursor = mResolver.query(uri,
65951f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                new String[]{Contacts.DISPLAY_NAME},
65961f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                null, null, Contacts.SORT_KEY_ALTERNATIVE);
65971f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65981f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterValues(cursor, "R", "S", "Sch", "St", "T");
65991f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterCounts(cursor,   1,   3,     1,    1,   1);
66001f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        cursor.close();
66011f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
66021f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
6603ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
6604ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
6605ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
6606ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6607ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6608ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6609ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
6610ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
6611ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
6612ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6613ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6614ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6615f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
6616f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
6617f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
6618f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
6619f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
6620f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
6621f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
6622f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
6623f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
6624f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
6625f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
6626f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
6627f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6628f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6629f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
6630f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
6631f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
6632f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
6633f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6634f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6635f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
6636f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
6637f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
6638f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
6639f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
6640f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
6641f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
6642f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
6643f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
66445fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
66455fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
66465fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
66475fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
66485fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
66495fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
66505fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
66515fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
66525fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
66535fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
66545fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
66555fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
66565fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
6657f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6658f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6659e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
6660e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
6661e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
6662e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
6663e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6664e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
6665e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
6666e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6667e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6668e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6669e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6670e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6671e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
6672e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
6673e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
6674e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
6675e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6676e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
6677e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
6678e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
6679e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
66808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri insertUri = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI,
66818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                blue);
6682e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6683e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
6684e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
6685e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6686e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6687e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6688e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6689e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
66903826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
66913826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
66923826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
66933826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
66943826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
66958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
66963826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
66973826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
66983826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
66993826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67003826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67013826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67023826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
67033826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        mActor.setAccounts(new Account[]{TestUtil.ACCOUNT_1});
67058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{TestUtil.ACCOUNT_1});
67063826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
6707bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
67083826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
67093826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67103826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67113826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67123826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
671309c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
671409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
671509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
671609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
67173826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
671809c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
671909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
672009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
6721b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
6722743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
6723b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
6724b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
6725b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
6726b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
6727b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
6728b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
6729b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
6730b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
6731b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
6732b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
6733b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
6734b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
673542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
673642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
673742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
673842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
673942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
674042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
674142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
674242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
674342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
674442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
674542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
674642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
674742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
674842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
674942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
675042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
675142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
675242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
675342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
675442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
675542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
675642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
675742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
675842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
675942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
67608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount,
67618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "4:12");
67628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
676342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
67648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccount,
67658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "3:4%121");
67668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doh");
676742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
676842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
676942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
677042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
677142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
677242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
677342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
677442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
677542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
677642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
677742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
677842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
677942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
678042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
678142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
678242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
678342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
678442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
678542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
678642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
678742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
678842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
678942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
679042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
679142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
679242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
679342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
679442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
679642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
679742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
679942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
680042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
680142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
680242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
680342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
680442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
680542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
680642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
680742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
680842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
680942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
681042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
681142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
681242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
681342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
681442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
681542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
681642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
681742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
681842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
681924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
682024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
682124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
682224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
682324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
682424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
682524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
682624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
682724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
682824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
682942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
683042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
683142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
683242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
683342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
683442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
683542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
683642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
683742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
683842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
683942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
684142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
684242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
684342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
684442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
684642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
684742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
684942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
685042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
685142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
685242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
685342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
685442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
685542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
685624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
685724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
685824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
685942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
686042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
686142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
686242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
686342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
686442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
686542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
686642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
686742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
686842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
686942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
687042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
687142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
687242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
687342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6874dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
6875dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6876dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6877dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
6878dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
68798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
68808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
68818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, null);
6882dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6883dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6884dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6885dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6886dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6887dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6888dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6889dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6890dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6891dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6892dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6893dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6894dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6895dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6896dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
6897dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
6898dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6899dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6900dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6901dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6902dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6903dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6904dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
69058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
69068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount);
69088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null);
6911dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6912dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6913dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6914dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6915dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6916dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6917dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
6918dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6919dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6920dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6921dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6922dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6923dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
6924dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
6925dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
6926dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
6927dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
6928dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
69298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo, RawContacts.STARRED, "1");
69338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null, RawContacts.STARRED, "1");
69358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r7 = RawContactUtil.createRawContact(mResolver, null);
6936dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6937dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6938dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6939dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6940dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6941dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6942dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
6943dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6944dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6945dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6946dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6947dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6948dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6949dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6950dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6951dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6952dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6953dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6954dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6955dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6956dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6957dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6958dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6959dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6960dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6961dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6962dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6963dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6964dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6965dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6966dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
6967dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
6968dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
6969dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6970dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6971dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6972dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6973dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6974dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6975dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6976dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6977dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6978dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6979dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6980dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
6981dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6982dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6983dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6984dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6985dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6986dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
6987dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6988dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6989dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6990dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6991dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6992dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6993dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6994dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6995dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6996dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6997dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6998dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6999dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7000dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
7001dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7002dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7003dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7004dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
70058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
70068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
70078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7008dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7009dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7010dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7011dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7012dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7013dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7014dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7015dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7016dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7017dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7018dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7019dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7020dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7021dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7022dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7023dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7024dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7025dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7026dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7027dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
7028dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
7029dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7030dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7031dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7032dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7033dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7034dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7035dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7036dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7037dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7038dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7039dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7040dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7041dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7042dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7043dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7044dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7045dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7046dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7047dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7048dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7049e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
7050dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
7051dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7052dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
7053dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
7054dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7055dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7056dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7057dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7058dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7059dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7060dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7061dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7062dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7063dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7064dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7065dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7066dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7067dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7068dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7069dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
7070dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7071dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7072dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7073dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7074dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7075dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
7076dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7077dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7078dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7079dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
70808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
70818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
70828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7084dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7085dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7086dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7087dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7088dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
7089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7090dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
7091dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
7092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
7093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
7094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7098dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7099dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7100dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7101dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7102dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7103dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7104dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7105dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7106dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7107dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7108dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
7109dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
7110dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
7111dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7112dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7113dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7114dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
7115dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7116dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7117dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7118dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
7119dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
7120dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
7121dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7122dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7123dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7124dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7125dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
7126dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7127dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7128dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
7129dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7130dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7131dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7132dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7133dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7134dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7135dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
7136dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
7137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
7138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7141dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7142dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7143dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7144dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
714597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
71468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
714797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
714897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
714997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
715097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
715197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
715297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
715397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
715497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
715597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
715697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
715797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
715897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
715997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
716097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
716197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
71628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
716397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
716497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
716597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
716697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
716797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
716897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
716997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
717097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
717197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
717297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
717397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
717497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
717597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
717697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
717797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
717897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
717997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
71808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
718197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
718297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
718397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
71848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
718597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
718697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
718797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
718897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
718997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
719097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
719197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
719297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
719397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
719497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
719597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
719697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
719797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
719897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
719997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
720097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
72017a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
72027a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
72037a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
72047a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72057a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
72067a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
720717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
72087a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72097a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72107a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72117a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72127a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72137a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72147a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72157a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72167a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72177a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
72187a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
72197a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
72207a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
72217a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
72227a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
72237a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
72247a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
72257a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
72267a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72277a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
722855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
72297a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
72307a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72317a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72327a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72337a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72347a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72357a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72367a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72377a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72387a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72397a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
7240084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    public void testBuildSingleRowResult() {
7241084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7242084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b"},
7243084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7244084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7245084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2}
7246084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7247084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7248084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7249084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b", "a", "b"},
7250084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7251084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7252084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2, 1, 2}
7253084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7254084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7255084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7256084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                null, // all columns
7257084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7258084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7259084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2}
7260084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7261084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7262084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7263084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            // Access non-existent column
7264084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            ContactsProvider2.buildSingleRowResult(new String[] {"a"}, new String[] {"b"},
7265084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                    new Object[] {1});
7266084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            fail();
7267084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } catch (IllegalArgumentException expected) {
7268084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7269084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7270084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7271084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    private void checkBuildSingleRowResult(String[] projection, String[] availableColumns,
7272084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            Object[] data, Integer[] expectedValues) {
7273084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        final Cursor c = ContactsProvider2.buildSingleRowResult(projection, availableColumns, data);
7274084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7275084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertTrue(c.moveToFirst());
7276084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(1, c.getCount());
7277084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(expectedValues.length, c.getColumnCount());
7278084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7279084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            for (int i = 0; i < expectedValues.length; i++) {
7280084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                assertEquals("column " + i, expectedValues[i], (Integer) c.getInt(i));
7281084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            }
7282084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } finally {
7283084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            c.close();
7284084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7285084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7286084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7287dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    public void testDataUsageFeedbackAndDelete() {
7288dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7289dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.install();
7290dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7291dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long startTime = sMockClock.currentTimeMillis();
7292dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
72938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "contact", "a");
7294dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1a = ContentUris.parseId(insertEmail(rid1, "email_1_a@email.com"));
7295dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1b = ContentUris.parseId(insertEmail(rid1, "email_1_b@email.com"));
7296dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1p = ContentUris.parseId(insertPhoneNumber(rid1, "555-555-5555"));
7297dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
72988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "contact", "b");
7299dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2a = ContentUris.parseId(insertEmail(rid2, "email_2_a@email.com"));
7300dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2p = ContentUris.parseId(insertPhoneNumber(rid2, "555-555-5556"));
7301dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7302dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Aggregate 1 and 2
7303dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rid1, rid2);
7304dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContactWithName(mResolver, "contact", "c");
7306dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3a = ContentUris.parseId(insertEmail(rid3, "email_3@email.com"));
7307dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3p = ContentUris.parseId(insertPhoneNumber(rid3, "555-3333"));
7308dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContactWithName(mResolver, "contact", "d");
7310dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did4p = ContentUris.parseId(insertPhoneNumber(rid4, "555-4444"));
7311dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7312dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid1 = queryContactId(rid1);
7313dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid3 = queryContactId(rid3);
7314dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid4 = queryContactId(rid4);
7315dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7316dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Make sure 1+2, 3 and 4 aren't aggregated
7317dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid3);
7318dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid4);
7319dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid3, cid4);
7320dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7321dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime
7322dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7323a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // First, there's no frequent.  (We use strequent here only because frequent is hidden
7324a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // and may be removed someday.)
7325a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7326a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7327dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 1. touch data 1a
7328dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a);
7329a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7330dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, there's a single frequent.  (contact 1)
7331a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(1, Contacts.CONTENT_STREQUENT_URI, null, null);
7332a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7333dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 1
7334dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7335dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7336dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 1a, 2a and 3a
7337dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a, did2a, did3a);
7338dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7339dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, contact 1 and 3 are in frequent.
7340dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7341dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7342dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 2
7343dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7344dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7345dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 2p (call)
7346dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did2p);
7347dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7348dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // There're still two frequent.
7349dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7350dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7351dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 3
7352dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7353dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7354dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 3. touch data 2p and 3p (short text)
7355dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, did2p, did3p);
7356dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7357dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's check the tables.
7358dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7359dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Fist, check the data_usage_stat table, which has no public URI.
7360dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7361dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.USAGE_TYPE_INT +
7362dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.TIMES_USED +
7363dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.LAST_TIME_USED +
7364dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7365dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did1a,
7366dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7367dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7368dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 2,
7369dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7370dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7371dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2a,
7372dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7373dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7374dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7375dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7376dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7377dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3a,
7378dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7379dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7380dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7381dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7382dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7383dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7384dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7385dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_CALL,
7386dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7387dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 2
7388dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7389dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7390dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7391dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7392dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7393dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7394dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7395dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3p,
7396dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7397dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7398dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7399dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7400dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7401dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7402dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7403dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Next, check the raw_contacts table
7404dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
7405dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid1,
7406dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7407dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 1
7408dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7409dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid2,
7410dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 3,
7411dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7412dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7413dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid3,
7414dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7415dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7416dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7417dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid4,
7418dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0,
7419dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, null // 4 wasn't touched.
7420dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7421dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7422dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7423dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Lastly, check the contacts table.
7424dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7425dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Note contact1.TIMES_CONTACTED = 4, even though raw_contact1.TIMES_CONTACTED +
7426dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // raw_contact1.TIMES_CONTACTED = 5, because in test 2, data 1a and data 2a were touched
7427dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // at once.
7428dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
7429dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid1,
7430dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 4,
7431dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7432dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7433dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid3,
7434dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 2,
7435dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7436dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7437dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid4,
7438dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 0,
7439dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, 0 // For contacts, the default is 0, not null.
7440dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7441dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7442a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7443dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's test the delete too.
7444b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7445a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7446a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Now there's no frequent.
7447a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7448a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7449dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // No rows in the stats table.
7450dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7451dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7452dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                new ContentValues[0]);
7453dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7454a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // The following values should all be 0 or null.
7455a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
7456a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.LAST_TIME_CONTACTED + ">0", null);
7457a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
7458a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.LAST_TIME_CONTACTED + ">0", null);
7459a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7460a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Calling it when there's no usage stats will still return a positive value.
7461b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7462a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki    }
7463a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
74648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /*******************************************************
74658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Delta api tests.
74668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
74678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_hasDeleteLog() {
74688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
74698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long start = sMockClock.currentTimeMillis();
74708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
74718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, start);
74728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up. Must also remove raw contact.
74748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
74758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
74768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_marksRawContactsForDeletion() {
74788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
74798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        String[] projection = new String[]{ContactsContract.RawContacts.DIRTY,
74818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.RawContacts.DELETED};
74828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        List<String[]> records = RawContactUtil.queryByContactId(mResolver, ids.mContactId,
74838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                projection);
74848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] arr : records) {
74858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[0]);
74868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[1]);
74878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
74888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
74908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
74918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
74928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactUpdate_updatesContactUpdatedTimestamp() {
74948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
74958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
74968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
74988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
75008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.Contacts.STARRED, 1);
75018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.update(mResolver, ids.mContactId, values);
75048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    // This implicitly tests the Contact create case.
75138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactCreate_updatesContactUpdatedTimestamp() {
75148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long startTime = System.currentTimeMillis();
75158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
75178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long lastUpdated = getContactLastUpdatedTimestampByRawContactId(mResolver, rawContactId);
75188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(lastUpdated > startTime);
75208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, rawContactId, true);
75238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
75268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
75318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.RawContacts.STARRED, 1);
75328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.update(mResolver, ids.mRawContactId, values);
75338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactPsuedoDelete_hasDeleteLogForContact() {
75428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, false);
75478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
75498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // clean up
75518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactDelete_hasDeleteLogForContact() {
75558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
75628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // already clean
75648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long getContactLastUpdatedTimestampByRawContactId(ContentResolver resolver,
75678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            long rawContactId) {
75688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long contactId = RawContactUtil.queryContactIdByRawContactId(mResolver, rawContactId);
75698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
75708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
75728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataInsert_updatesContactLastUpdatedTimestamp() {
75758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        insertPhoneNumberAndReturnDataId(ids.mRawContactId);
75818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataDelete_updatesContactLastUpdatedTimestamp() {
75908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
75948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.delete(mResolver, dataId);
75998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataUpdate_updatesContactLastUpdatedTimestamp() {
76088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
76128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
76168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
76178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "555-5555");
76188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.update(mResolver, dataId, values);
76198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long insertPhoneNumberAndReturnDataId(long rawContactId) {
76288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = insertPhoneNumber(rawContactId, "1-800-GOOG-411");
76298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContentUris.parseId(uri);
76308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsDelete_isUnsupported() {
76338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, URI);
76358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = ContentUris.withAppendedId(URI, 1L);
76378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, uri);
76388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsInsert_isUnsupported() {
76418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertInsertIsUnsupported(mResolver, URI);
76438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsByContactId() {
76478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
76488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND,
76508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
76518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsAll() {
76548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final int numDeletes = 10;
76558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Since we cannot clean out delete log from previous tests, we need to account for that
76578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // by querying for the count first.
76588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long startCount = DeletedContactUtil.getCount(mResolver);
76598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (int i = 0; i < numDeletes; i++) {
76618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertContactCreateDelete();
76628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
76638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long endCount = DeletedContactUtil.getCount(mResolver);
76658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(numDeletes, endCount - startCount);
76678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsSinceTimestamp() {
76708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Before
76738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> beforeIds = new HashSet<Long>();
76748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
76758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
76768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long start = sMockClock.currentTimeMillis();
76788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // After
76808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> afterIds = new HashSet<Long>();
76818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final String[] projection = new String[]{
76868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_ID,
76878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
76888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        };
76898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final List<String[]> records = DeletedContactUtil.querySinceTimestamp(mResolver, projection,
76908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                start);
76918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] record : records) {
76928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check ids to make sure we only have the ones that came after the time.
76938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            final long contactId = Long.parseLong(record[0]);
76948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertFalse(beforeIds.contains(contactId));
76958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(afterIds.contains(contactId));
76968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check times to make sure they came after
76988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(Long.parseLong(record[1]) > start);
76998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
77008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
77018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
77038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Create a contact. Assert it's not present in the delete log. Delete it.
77048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * And assert that the contact record is no longer present.
77058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     *
77068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * @return The contact id and raw contact id that was created.
77078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
77088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private DatabaseAsserts.ContactIdPair assertContactCreateDelete() {
77098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
77108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(CommonDatabaseUtils.NOT_FOUND,
77128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
77138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
77158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.delete(mResolver, ids.mContactId);
77168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertFalse(ContactUtil.recordExistsForContactId(mResolver, ids.mContactId));
77188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ids;
77208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
772181fea08280784b319b936a3506788d595c6ce2adYorke Lee
77228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
77238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * End delta api tests.
77248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     ******************************************************/
77258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
772681fea08280784b319b936a3506788d595c6ce2adYorke Lee    /*******************************************************
772781fea08280784b319b936a3506788d595c6ce2adYorke Lee     * Pinning support tests
772881fea08280784b319b936a3506788d595c6ce2adYorke Lee     */
772981fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateForceStar() {
773081fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
773181fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
773281fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
773381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
773481fea08280784b319b936a3506788d595c6ce2adYorke Lee
773581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final int unpinned = PinnedPositions.UNPINNED;
773681fea08280784b319b936a3506788d595c6ce2adYorke Lee
773781fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
773881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
773981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
774081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
774181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0)
774281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
774381fea08280784b319b936a3506788d595c6ce2adYorke Lee
774481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
774581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, unpinned),
774681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
774781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned),
774881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, unpinned)
774981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
775081fea08280784b319b936a3506788d595c6ce2adYorke Lee
775181fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId, 2);
775281fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
775381fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
775481fea08280784b319b936a3506788d595c6ce2adYorke Lee                values, null, null);
775581fea08280784b319b936a3506788d595c6ce2adYorke Lee
775681fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Pinning a contact should automatically star it if we specified the boolean parameter
775781fea08280784b319b936a3506788d595c6ce2adYorke Lee
775881fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
775981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
776081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
776181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 1),
776281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 1)
776381fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
776481fea08280784b319b936a3506788d595c6ce2adYorke Lee
776581fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Make sure the values are propagated to raw contacts
776681fea08280784b319b936a3506788d595c6ce2adYorke Lee
776781fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
776881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
776981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
777081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
777181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2)
777281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
777381fea08280784b319b936a3506788d595c6ce2adYorke Lee
777481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues unpin = cv(i3.mContactId, unpinned);
777581fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
777681fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
777781fea08280784b319b936a3506788d595c6ce2adYorke Lee                unpin, null, null);
777881fea08280784b319b936a3506788d595c6ce2adYorke Lee
777981fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Unpinning a contact should automatically unstar it
778081fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
778181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
778281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
778381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
778481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 1)
778581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
778681fea08280784b319b936a3506788d595c6ce2adYorke Lee
778781fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
778881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mRawContactId, RawContacts.PINNED, 1, RawContacts.STARRED, 1),
778981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
779081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
779181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned,
779281fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
779381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mRawContactId, RawContacts.PINNED, 2, RawContacts.STARRED, 1)
779481fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
779581fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
779681fea08280784b319b936a3506788d595c6ce2adYorke Lee
779781fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateDontForceStar() {
779881fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
779981fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
780081fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
780181fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
780281fea08280784b319b936a3506788d595c6ce2adYorke Lee
780381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final int unpinned = PinnedPositions.UNPINNED;
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, values, null, null);
780781fea08280784b319b936a3506788d595c6ce2adYorke Lee
780881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Pinning a contact should not automatically star it
780981fea08280784b319b936a3506788d595c6ce2adYorke Lee
781081fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
781181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
781281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
781381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 0),
781481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
781581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
781681fea08280784b319b936a3506788d595c6ce2adYorke Lee
781781fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Make sure the values are propagated to raw contacts
781881fea08280784b319b936a3506788d595c6ce2adYorke Lee
781981fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
782081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
782181fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
782281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
782381fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
782481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
782581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
782681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2,
782781fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
782881fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
782981fea08280784b319b936a3506788d595c6ce2adYorke Lee
783081fea08280784b319b936a3506788d595c6ce2adYorke Lee
783181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Manually star contact 3
783281fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertEquals(1, updateItem(Contacts.CONTENT_URI, i3.mContactId, Contacts.STARRED, "1"));
783381fea08280784b319b936a3506788d595c6ce2adYorke Lee
783481fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Check the third contact and raw contact is starred
783581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
783681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
783781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
783881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 1),
783981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
784081fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
784181fea08280784b319b936a3506788d595c6ce2adYorke Lee
784281fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
784381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
784481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
784581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
784681fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
784781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
784881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
784981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2,
785081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
785181fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
785281fea08280784b319b936a3506788d595c6ce2adYorke Lee
785381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final ContentValues unpin = cv(i3.mContactId, unpinned);
785481fea08280784b319b936a3506788d595c6ce2adYorke Lee
785581fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, unpin, null, null);
785681fea08280784b319b936a3506788d595c6ce2adYorke Lee
785781fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Unpinning a contact should not automatically unstar it
785881fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
785981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 0),
786081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
786181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 1),
786281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
786381fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
786481fea08280784b319b936a3506788d595c6ce2adYorke Lee
786581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
786681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mRawContactId, RawContacts.PINNED, 1, RawContacts.STARRED, 0),
786781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
786881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
786981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned,
787081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
787181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mRawContactId, RawContacts.PINNED, 2, RawContacts.STARRED, 0)
787281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
787381fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
787481fea08280784b319b936a3506788d595c6ce2adYorke Lee
787581fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsUpdateIllegalValues() {
787681fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
787781fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
787881fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
787981fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
788081fea08280784b319b936a3506788d595c6ce2adYorke Lee
788181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
788281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
788381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
788481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
788581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
788681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
788781fea08280784b319b936a3506788d595c6ce2adYorke Lee
788845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Unsupported string
788945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 1, i3.mContactId, 3, i4.mContactId,
789045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                "undemotemeplease!");
789181fea08280784b319b936a3506788d595c6ce2adYorke Lee        try {
789281fea08280784b319b936a3506788d595c6ce2adYorke Lee            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values, null, null);
789345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            fail("Pinned position must be an integer.");
789481fea08280784b319b936a3506788d595c6ce2adYorke Lee        } catch (IllegalArgumentException expected) {
789581fea08280784b319b936a3506788d595c6ce2adYorke Lee        }
789681fea08280784b319b936a3506788d595c6ce2adYorke Lee
789745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Float
789845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values2 = cv(i1.mContactId, "1.1");
789981fea08280784b319b936a3506788d595c6ce2adYorke Lee        try {
790045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI, values2, null, null);
790145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee            fail("Pinned position must be an integer");
790281fea08280784b319b936a3506788d595c6ce2adYorke Lee        } catch (IllegalArgumentException expected) {
790381fea08280784b319b936a3506788d595c6ce2adYorke Lee        }
790481fea08280784b319b936a3506788d595c6ce2adYorke Lee
790581fea08280784b319b936a3506788d595c6ce2adYorke Lee        // nothing should have been changed
790681fea08280784b319b936a3506788d595c6ce2adYorke Lee
790781fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
790881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
790981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
791081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED),
791181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
791281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
791381fea08280784b319b936a3506788d595c6ce2adYorke Lee
791481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
791581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
791681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
791781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED),
791881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED)
791981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
792081fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
792181fea08280784b319b936a3506788d595c6ce2adYorke Lee
792281fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsAfterJoinAndSplit() {
792381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
792481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
792581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
792681fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
792745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i5 = DatabaseAsserts.assertAndCreateContact(mResolver);
792845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i6 = DatabaseAsserts.assertAndCreateContact(mResolver);
792981fea08280784b319b936a3506788d595c6ce2adYorke Lee
793045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 1, i2.mContactId, 2, i3.mContactId, 3,
793145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                i5.mContactId, 5, i6.mContactId, 6);
793281fea08280784b319b936a3506788d595c6ce2adYorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon()
793381fea08280784b319b936a3506788d595c6ce2adYorke Lee                .appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").build(),
793481fea08280784b319b936a3506788d595c6ce2adYorke Lee                values, null, null);
793581fea08280784b319b936a3506788d595c6ce2adYorke Lee
793681fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 1 and 4 together.
793781fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i1.mRawContactId,
793881fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
793981fea08280784b319b936a3506788d595c6ce2adYorke Lee
794081fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If only one contact is pinned, the resulting contact should inherit the pinned position
794181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
794281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
794381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
794445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3),
794545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
794645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
794781fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
794881fea08280784b319b936a3506788d595c6ce2adYorke Lee
794981fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
795081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
795181fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
795281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
795381fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
795481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
795581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
795681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
795745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
795845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
795945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
796045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
796145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
796281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
796381fea08280784b319b936a3506788d595c6ce2adYorke Lee
796481fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 2 and 3 together.
796581fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i2.mRawContactId,
796681fea08280784b319b936a3506788d595c6ce2adYorke Lee                i3.mRawContactId);
796781fea08280784b319b936a3506788d595c6ce2adYorke Lee
796881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If both raw contacts are pinned, the resulting contact should inherit the lower
796981fea08280784b319b936a3506788d595c6ce2adYorke Lee        // pinned position
797081fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
797181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
797245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
797345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
797445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
797581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
797681fea08280784b319b936a3506788d595c6ce2adYorke Lee
797781fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
797881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
797981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2),
798081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
798145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED,
798245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        PinnedPositions.UNPINNED),
798345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5),
798445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6)
798581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
798681fea08280784b319b936a3506788d595c6ce2adYorke Lee
798781fea08280784b319b936a3506788d595c6ce2adYorke Lee        // split the aggregated raw contacts
798881fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE, i1.mRawContactId,
798981fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
799081fea08280784b319b936a3506788d595c6ce2adYorke Lee
799181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // raw contacts should be unpinned after being split, but still starred
799281fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
799381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
799481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
799581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
799681fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
799781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
799881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
799981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
800045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
800145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
800245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
800345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
800445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
800545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
800645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
800745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
800845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
800945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // now demote contact 5
801045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues cv = cv(i5.mContactId, PinnedPositions.DEMOTED);
801145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().build(),
801245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv, null, null);
801345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
801445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Get new contact Ids for contacts composing of raw contacts 1 and 4 because they have
801545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // changed.
801645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
801745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
801845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
801945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
802045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
802145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
802245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
802345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED),
802445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
802545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
802645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
802745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // aggregate contacts 5 and 6 together
802845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i5.mRawContactId,
802945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                i6.mRawContactId);
803045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
803145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // The resulting contact should have a pinned value of 6
803245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
803345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
803445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
803545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
803645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 6)
803745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
803845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    }
803945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
804045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    public void testPinnedPositionsAfterDemoteAndUndemote() {
804145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
804245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
804345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
804445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values = cv(i1.mContactId, 0, i2.mContactId, PinnedPositions.DEMOTED);
804545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
804645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Pin contact 1 and demote contact 2
804745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
804845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                appendQueryParameter(PinnedPositions.STAR_WHEN_PINNING, "true").
804945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                build(), values, null, null);
805045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
805145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
805245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
805345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED,
805445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
805545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
805645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
805745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
805845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
805945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
806045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.DEMOTED,
806145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0)
806245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
806345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
806445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Now undemote both contacts
806545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final ContentValues values2 = cv(i1.mContactId, PinnedPositions.UNDEMOTE, i2.mContactId,
806645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                PinnedPositions.UNDEMOTE);
806745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        mResolver.update(ContactsContract.PinnedPositions.UPDATE_URI.buildUpon().
806845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                build(), values2, null, null);
806945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
807045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Contact 1 remains pinned at 0, while contact 2 becomes unpinned
807145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
807245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0, Contacts.STARRED, 1),
807345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED,
807445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
807545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
807645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
807745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
807845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 0,
807945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
808045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
808181fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
808281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
808381fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
808481fea08280784b319b936a3506788d595c6ce2adYorke Lee
808581fea08280784b319b936a3506788d595c6ce2adYorke Lee    /**
808681fea08280784b319b936a3506788d595c6ce2adYorke Lee     * End pinning support tests
808781fea08280784b319b936a3506788d595c6ce2adYorke Lee     ******************************************************/
80888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
8089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
80908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Cursor c = mResolver.query(TestUtil.maybeAddAccountQueryParameters(Data.CONTENT_URI,
80918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account),
8092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
8093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
8094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
8095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
8096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
8097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
809842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
809942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
8100bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
810142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
810242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
8103bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
8104bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
8105bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
8106bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
8107bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
8108bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
8109bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
811042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
8111bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
8112bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
811342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
811442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
811542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
811642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
811742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
811842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
8119f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
8120f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
8121f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
8122f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
8123f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
81244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
81254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8126aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
812724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
812824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
812924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
813024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
813124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
813224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
813324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
813448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
813524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
813648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
813748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
813848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
813948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8140aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
814148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
8142aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
81438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
814448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
814548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
814648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
814724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
814824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
814924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
815024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
815124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
81528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
815324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
815424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
815524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
815648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
8157aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
815824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
815924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
816024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
816124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
816224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
816324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
816424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
81654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
81664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
81674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
81684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
816924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
817024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
817124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
817224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
817324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
81744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
81754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
81764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
81774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
81789dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
81799dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
81809dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
81819dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
81829dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
81839dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
81844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8185aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
81865d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
81874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
81884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
81894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
81904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
819124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
819248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
81934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
81944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
819524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
819624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
819724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
819824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
819924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
820024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
820124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
820224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
820324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
820424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
820524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
820624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
820724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
820824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
820924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
821024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
821124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
821224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
821324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
821424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
821524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
821624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
821724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
821824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
821924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
822024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
822124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
822224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
82234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
82244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
82254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
82264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
82274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
82284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
82294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
82304a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
82314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
82324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
82334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
82344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
82354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
82364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
82374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
82384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
82394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
82404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
82414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
82424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
82434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
82444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
82454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
82464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
82474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
82484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
82494928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
82504928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
82514928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
82524928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
82534928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
82544928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
82554928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
82564928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
82574928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
82584928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
8259dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(0, updateDataUsageFeedback(usageType, dataId));
82604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
82614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
82624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
82634928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
8264dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
8265dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    private void updateDataUsageFeedback(String usageType, Uri resultUri) {
8266dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final long id = ContentUris.parseId(resultUri);
8267dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final boolean successful = updateDataUsageFeedback(usageType, id) > 0;
8268dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertTrue(successful);
8269dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
8270dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
8271dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    private int updateDataUsageFeedback(String usageType, long... ids) {
8272dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final StringBuilder idList = new StringBuilder();
8273dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        for (long id : ids) {
8274dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            if (idList.length() > 0) idList.append(",");
8275dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            idList.append(id);
8276dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        }
8277dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        return mResolver.update(DataUsageFeedback.FEEDBACK_URI.buildUpon()
8278dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendPath(idList.toString())
8279dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
8280dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .build(), new ContentValues(), null, null);
8281dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    }
8282a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8283a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasChineseCollator() {
8284a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8285a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8286a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.CHINA)) {
8287a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8288a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8289a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8290a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8291a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
8292a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8293a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasJapaneseCollator() {
8294a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8295a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8296a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.JAPAN)) {
8297a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8298a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8299a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8300a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8301a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
83021f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
83031f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    private boolean hasGermanCollator() {
83041f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
83051f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        for (int i = 0; i < locale.length; i++) {
83061f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            if (locale[i].equals(Locale.GERMANY)) {
83071f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                return true;
83081f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            }
83091f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
83101f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        return false;
83111f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
8312d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
8313