ContactsProvider2Test.java revision 9aec6b8422f8d153a91a241f1b10d6e48d338bb8
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;
5724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
5809c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
5933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6062318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
61916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikovimport android.provider.ContactsContract.SearchSnippetColumns;
6289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
6382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
65f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
66dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
677d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
68d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
69f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
7038210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
7138210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.internal.util.ArrayUtils;
7238210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
73a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.ContactsColumns;
7438210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
7538210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
7638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
77a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
7838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables;
798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.CommonDatabaseUtils;
808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.ContactUtil;
818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DataUtil;
828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DatabaseAsserts;
838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DeletedContactUtil;
848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.RawContactUtil;
858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.TestUtil;
8638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.tests.R;
8738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Lists;
8838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Sets;
89d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
9042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
9142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
92f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport java.util.HashSet;
973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport java.util.Set;
1005dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
101d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
102d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
103d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
104d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
105d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
10623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki   adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
10723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki           com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
108d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
109d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
110d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
111d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
112d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
1138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private static final String TAG = ContactsProvider2Test.class.getSimpleName();
11447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
115dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
116dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
117dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
118dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
119dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
120dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
121dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
122dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
123dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
124dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
125a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
126a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
127a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
128a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
129dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
133dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
134f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1353d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1363d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
137dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
138dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
139dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
14024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
142dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
143dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
144dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
147dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
148dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
149dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
1508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
151dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
152dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
153dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
15463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentProjection() {
15563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI, new String[]{
15663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
15763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
15863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
15963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
16063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
16163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
16263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
16363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
164a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
165a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
166a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
167a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
16863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
16963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
17063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
17163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
17263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
17363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
17463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
17563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
17663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
17763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
17863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
17963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
18063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
18163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
18263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
18363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
18463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
18563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
18663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
18763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
18863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
1898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
19063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
19163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
19263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
19363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
19463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
19563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentPhoneOnlyProjection() {
19663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI.buildUpon()
19763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build(),
19863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                new String[] {
19963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
20063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
20163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
20263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
20363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
20463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
20563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
20663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
207a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
208a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
209a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
210a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
21163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
21263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
21363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
21463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
21563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
21663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
21763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
21863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
21963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
22063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
22163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
22263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
22363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
22463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
22563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
22663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
22763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
22863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
22963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
23063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
23163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
2328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
23363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
23463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
23563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.NUMBER,
23663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.TYPE,
23763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.LABEL,
23863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
23963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
24063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
242dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
243dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
244dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
245dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
246dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
247dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
248dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
249dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
250dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
251dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
252a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
253a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
254a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
255a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
256dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
257dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
258dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
259dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
260dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
261f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2623d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2633d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
264dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
265dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
26724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
268dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
269dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
271dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
272dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
273dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
274dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
2778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
27830cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov                SearchSnippetColumns.SNIPPET,
279dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
282dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
283dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
284dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
28843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
28943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
29224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
295dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
298dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
299dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
303a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_PRIMARY,
304a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
305a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
306a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
309dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
310dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
311dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
312dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
313dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
324dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
325dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
326dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
327dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
328dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
329dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
333dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
345dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
346dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
347dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
348dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
349dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
350dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
351dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
352dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
353dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
354dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
355dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
356216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
357216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
358dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
359dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
36043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
36143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
362dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
363dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
364dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
365dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
36624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
367dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
368dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
369dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
370dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
371dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
372dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
373dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
374dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
375a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
376a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
377a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
378a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
379dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
380dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
381dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
382dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
383dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
384f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
3853d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
3863d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
387dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
388dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
389dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
390dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
391cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
392dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
393dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
394dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
395dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
396dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
397dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
398dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
3998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
400dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
401dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
402dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
403dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
404dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
405dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
406dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
407dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
408dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
409dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
410dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
411dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
412dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
413dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
414dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
415dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
416dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
417dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
418dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
419dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
420dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
421dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
422dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
423dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
424dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
425dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
426dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
427dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
428dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
440216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
441216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
44224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
445dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
446dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
449dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
450dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
451a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
452a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
453a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
454a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
460f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4623d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
463cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
464dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
465dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
466dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
470dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
471dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
472dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
475dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
476dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
477dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
478dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
479a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
480a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
481a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
482a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
483a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
484a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
485a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
486a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
487a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
488a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
489a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
490a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
491a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
492a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
493a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
494a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
495a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
496a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
497a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
498a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
499a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
500a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
501a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
502a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
503a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
504a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
505a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
506a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
507a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
508a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
509a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
510a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
511a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
512a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
513a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
514a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
515a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
516a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
517a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
518a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
519a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
520a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
52143368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
52243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
523a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
524a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
525a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
526a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
527a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
528a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
529a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
530a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
531a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
532a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
533a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
534a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
535a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
536a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
537a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
538a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
539a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
540a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
541a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
542a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
543a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
544a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
545a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
546a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
547a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
548a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
549f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
5503d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
5513d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
552a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
553a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
55424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
555a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
556a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
557cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
558a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
559a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
560a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
561a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
562a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
563a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
564a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
5658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
566a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
567a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
568a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
569a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
570dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
571dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
572dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
573dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
574dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
575dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
576dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
57743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
57843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
579dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
580dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
581dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
582dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
583dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
584dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
585dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
586dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
587dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
588dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
58924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
590dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
591dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
592dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
593dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
594dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
595dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
596dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
597dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
598dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
599dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
607dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
608dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
614dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
618dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
619dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
620dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
621dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
622dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
623dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
624dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
625dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
626dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
627dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
628dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
6293d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
6303d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
631dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
632dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
633dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
634dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
635dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
636dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
6372530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
638dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
639dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
640dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
641dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
642dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
643dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
644dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
645dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
64643368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
64743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
648dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
649dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
650dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
651dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
652dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
653dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
654dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
655dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
656dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
657dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
658dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
659dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
660dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
661c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
662dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
663dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
664dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
665dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
666dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
667dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
668dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
669dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
670dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
671dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
672dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
673dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
67443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
67543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
676dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
677dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
678dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
679dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
680dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
681dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
682dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
683dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
684dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
685dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
686dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
687dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
688dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
689c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
690dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
691dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
692dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
693dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
694dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
695dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
69618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
697dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
698dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
699dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
700dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
701dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
702dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
703dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
704dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
705dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
706dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
707dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
708dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
709dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
710dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
711dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
712dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
713f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET,
714dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
715dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
716dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
717dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
718dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
719dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
720dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
721dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
722dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
723dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
724dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
725dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
726dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
727dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
728dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
729dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
730dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
731dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
732dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
733dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
734dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
735dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
736dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
737dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
738dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
739dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
740dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
741dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
742dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
743dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
744dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
745dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
746dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
747dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
748dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
749dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
750778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
751778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
752dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
753dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
754dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
7553cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
7563cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
7573cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7583cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
7593cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
7609d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(RawContacts.DATA_SET, "ds");
7613cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
7623cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
7633cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
7643cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
7653cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
7663cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
7673cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
7683cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
7693cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
7703cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
7713cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
7723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
7733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
7743cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7753cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
7764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
7773cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7783cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
7794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
78081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
7813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
7823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
7832149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
7842149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
7852149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
7872149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
7882149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
7892149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7902149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
7912149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
7922149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7932149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
7942149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
7952149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
7962149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7972149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
7982149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
7992149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
8002149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
8012149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8022149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8032149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8042149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
8052149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
8062149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
8072149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8082149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8092149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8102149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
8112149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
8122149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
8132149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
8142149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
8152149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8162149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8172149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8182149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
8192149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8202149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8212149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8222149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
8232149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8242149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8252149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
8262149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8272149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
828a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
829a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
830a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
831a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
832a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
834a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
835a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8365d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
837a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
839a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
840a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
841a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
842a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
843a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
844a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
845a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
846a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
847a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
848a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
849a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
850a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
851a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
852a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
853a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
854a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
856a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
857a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8585d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
859a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
861a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
862a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
863a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
864a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
865a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
866a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
867a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
868a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
869a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
870a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
871a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
872a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
873a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
874a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
875a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
876a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
877a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
878a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
879a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
880a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
881a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
882a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
883a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
884a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
885a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
886a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
887a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
888a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
889a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
890a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
891a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
892a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
893a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
894a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
895a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
896a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
897a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
898a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
899a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
900a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
901a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
902a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
903a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
904a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
905a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
906a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
907a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
908a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
909a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
910a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
911a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
912a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
913a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
914a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
915a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
916a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
917a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
918a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
919a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
920a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
921a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
922a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
923a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
924a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
925a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
926a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
927a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
928a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
929a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
930a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
931a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
932a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
933a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
934a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
935a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
936a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
937a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
938a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
939a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
940a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
941a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
942a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
943a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
944a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
945a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
9463cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
9478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
9484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
9504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
9514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
9524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
9534a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
9554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
9564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
9574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
9594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
9614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
9624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
9634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
9644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
9654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
9674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
9684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
9694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
97081d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
9714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
9723cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
97389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
97489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
97589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
9768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
9778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
9788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
9798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doe");
98089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(dataUri1, account1);
9828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(dataUri2, account2);
98389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
98489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
98589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
98689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
9874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
9887d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
9893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
9904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
9914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
9924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
9934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
9944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
9954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
9974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
9984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
9998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
10004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
10014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
10024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
10073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
10104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
10124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
10134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
10164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
10174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
10184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
10194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
102048828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
10214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
10224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1024cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    public void testPhonesWithMergedContacts() {
10258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1026cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "123456789", true);
1027cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
1029cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "123456789", true);
1030cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10310992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
10320992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki                rawContactId1, rawContactId2);
10330992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        assertNotAggregated(rawContactId1, rawContactId2);
10340992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki
1035cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1036cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "123456789");
1037cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1038cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Phone.NUMBER, "123456789");
1039cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10400992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // There are two phone numbers, so we should get two rows.
1041cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
1042cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10430992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now set the dedupe flag.  But still we should get two rows, because they're two
10440992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // different contacts.  We only dedupe within each contact.
10458ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Phone.CONTENT_URI.buildUpon()
10468ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
10478ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
10488ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, new ContentValues[] {values1, values1});
10498ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10500992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now join them into a single contact.
1051cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
1052cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa                rawContactId1, rawContactId2);
1053cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1054cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertAggregated(rawContactId1, rawContactId2, "123456789");
1055cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
10560992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Contact merge won't affect the default result of Phone Uri, where we don't dedupe.
10578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
10588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
10590992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now we dedupe them.
10608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values1);
1061cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    }
1062cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1063904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    public void testPhonesNormalizedNumber() {
10648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver);
1065904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1066904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Write both a number and a normalized number. Those should be written as-is
1067904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final ContentValues values = new ContentValues();
1068904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.RAW_CONTACT_ID, rawContactId);
1069904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1070904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1234");
1071904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "5678");
1072904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.TYPE, Phone.TYPE_HOME);
1073904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1074904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
1075904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
107610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the lookup table.
1077904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1078904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1079904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1080904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1081904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
108210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the data table.
108310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
108410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1234", Phone.NORMALIZED_NUMBER, "5678")
108510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
108610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1087904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace both in an UPDATE
1088904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1089904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "4321");
1090904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1091904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1092904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1093904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1094904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1095904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "4321"), null, null));
1096904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1097904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1098904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1099904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1100904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
110110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
110210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "4321", Phone.NORMALIZED_NUMBER, "8765")
110310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
110410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1105904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NUMBER ==> NORMALIZED_NUMBER will be inferred (we test that by making
1106904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // sure the old manual value can not be found anymore)
1107904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
110810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "+1-800-466-5432");
1109904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1110904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1111904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
111210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1113904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1114904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1115904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1116904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
111710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
111810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
111910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
112010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1121904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NORMALIZED_NUMBER ==> call is ignored, things will be unchanged
1122904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1123904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1124904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1125904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1126904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
112710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1128904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1129904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1130904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
113110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
113210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
113310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
113410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
113510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
113610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Replace NUMBER with an "invalid" number which can't be normalized.  It should clear
113710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // NORMALIZED_NUMBER.
113810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
113910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 1. Set 999 to NORMALIZED_NUMBER explicitly.
114010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
114110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "888");
114210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NORMALIZED_NUMBER, "999");
114310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
114410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(1,
114610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
114710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
114810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
114910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "888", Phone.NORMALIZED_NUMBER, "999")
115010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
115110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 2. Set an invalid number to NUMBER.
115310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
115410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "1");
115510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
115610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
115710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(0,
115810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
115910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
116010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
116110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1", Phone.NORMALIZED_NUMBER, null)
116210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
1163904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    }
1164904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
11654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
1166e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
1167e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1168e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1169e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
1170e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
1171e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
1172e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1173e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
1174e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
1175e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1176e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
1177e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
1178e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
1179e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
1180e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
1181e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
1182e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
1183e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
11848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot",
11858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale", TestUtil.ACCOUNT_1);
11865e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
11875e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
11888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Chilled",
11898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Guacamole", TestUtil.ACCOUNT_2);
11902a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
119158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
119258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
11935e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1194e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
11954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
11964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
11974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
11985e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
11994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
12004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
12015e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
12024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1203e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
12045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
12055e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1206e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
12075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
12085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1209e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
12105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
121145d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
1212e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
121345d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
121458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
121558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
121658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
121758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
121858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
121958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
122058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
122158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
122258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
122358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
122458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
122558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
122658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
122758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
122858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
122958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
123058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
123158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
123258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
123358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
123458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
123558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
1236e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
1237dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValues(filterUri6, new ContentValues[]{values1, values2, values3});
1238e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1239e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
1240e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1241e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1242e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1243e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1244e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1245e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1246e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1247e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1248e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1249e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1250e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1251e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1252e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1253e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1254e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1255e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1256e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1257e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1258e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1259e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1260e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1261e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1262e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1263e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1264e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1265e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1266e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1267e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1268e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1269e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1270e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
127158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
12724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
12734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
12744c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    public void testPhonesFilterSearchParams() {
12758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "Dad", null);
12764c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid1, "123-456-7890");
12774c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "Mam", null);
12794c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid2, "323-123-4567");
12804c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12814c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // By default, "dad" will match both the display name and the phone number.
12824c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // Because "dad" is "323" after the dialpad conversion, it'll match "Mam" too.
12834c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12844c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad").build(),
12854c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890"),
12864c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
12874c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
12884c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12894c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
12904c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
12914c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
12924c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890")
12934c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
12944c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
12954c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
12964c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
12974c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
12984c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
12994c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
13004c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13014c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13024c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
1303dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
1304dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
1305dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .build()
1306dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        );
13074c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    }
13084c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
1309e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1310e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1311e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1312e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1313e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1314e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1315e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1316e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
13178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
13184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
13194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1320ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1321ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1322ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
13234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1324e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1325e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1326e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1327e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1328e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1329e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1330e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1331e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1332e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1333ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
13344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1335892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
133634984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1337e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
133834984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
13396db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13406db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // A wrong area code 799 vs 800 should not be matched
13416db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "7994664411");
13426db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
1343892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1344892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1345892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1346892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1347892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1348892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1349892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1350892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1351892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1352892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1353892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1354892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1355892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1356892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1357892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1359892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1360892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1361892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1362892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1363892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1364892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1365892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1366892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1367892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1368892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1369892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1370892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13716db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with wrong area code
13726db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "649 861 0000");
13736db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13746db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13756db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digits in mistyped area code
13766db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "5 861 0000");
13776db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13786db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
13796db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digit in mistyped area code
13806db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "65 861 0000");
13816db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
13826db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
1383892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1384892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1385892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1386892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1387892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1388892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1389892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
13908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot1", "Tamale");
1391892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1392892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1393892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1394892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1395892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1396892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1397892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1398892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1399892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1400892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1401892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1402892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1403892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1404892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1405892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1406892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1407892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1408892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1409892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
14108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot2", "Tamale");
1411892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1412892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1413892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1414892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1415892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1416892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1417892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1418892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1419892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1420892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1421892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
14224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
14234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
142456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
14256db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Checks the logic that relies on phone_number_compare_loose(Gingerbread) as a fallback
14266db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        //for phone number lookups.
142756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
142856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
142956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
143056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
143156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
143256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
143456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
143556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
143656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
143756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
143856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
143956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
144056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
144156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
144256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
144356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
14446db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Number with international (+972) prefix should also match.
14456db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(1, getCount(Uri.withAppendedPath(
14466db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee                PhoneLookup.CONTENT_FILTER_URI, "+97297427289"), null, null));
144756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
144856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
144956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
145056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
145156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
145356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
145456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
145556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
145656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
145756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
145856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
145956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
146056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
146256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
146356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
146456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
146556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
146656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
146756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
146856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
14698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
147056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
147156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
147356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
147456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
147656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
147756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
147856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
147956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
148056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
148356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
148456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
148556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
148656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
148756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1488a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    public void testPhoneLookupUseStrictPhoneNumberCompare() {
1489a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Test lookup cases when mUseStrictPhoneNumberComparison is true
1490a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
1491a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
1492a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Get and save the original value of mUseStrictPhoneNumberComparison so that we
1493a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // can restore it when we are done with the test
1494a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
1495a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
1496a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1497a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1498a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        try {
1499a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            String fullNumber = "01197297427289";
1500a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            ContentValues values = new ContentValues();
1501a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.CUSTOM_RINGTONE, "d");
1502a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1503a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            long rawContactId = ContentUris.parseId(
1504a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    mResolver.insert(RawContacts.CONTENT_URI, values));
15058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
1506a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, fullNumber);
1507a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "5103337596");
1508a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "+19012345678");
1509a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for full number
1510a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1511a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
1512a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1513a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra digit at the front
1514a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1515a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
1516a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for mispelled area code
1517a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1518a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
1519a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1520a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with dashes
1521a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1522a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
1523a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1524a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with international code
1525a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1526a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
1527a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1528a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1529a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra 0 in front
1530a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1531a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
1532a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1533a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1534a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for different country code
1535a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1536a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
1537a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1538a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        } finally {
1539a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // restore the original value of mUseStrictPhoneNumberComparison
1540a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // upon test completion or failure
1541a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
1542a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        }
1543a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    }
1544a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1545653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
1546653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
1547653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1548653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1549653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
15508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1551653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
1552653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1553653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1554ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
1555ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
1556ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
1557653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1558653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1559653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1560653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1561653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1562ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1563ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
1564653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1565653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
1566653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1567653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
1568653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1569653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1570ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1571653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
1572653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1573653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
1574653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
1575653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
1576653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
1577ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
1578ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
157981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
1580653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
1581653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
1582e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
1583e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
15848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Meghan", "Knox");
1585e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
1586e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
1587e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
15888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
1589e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
1590e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
1591e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
1592e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1593e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1594e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
1595e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
1596e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
1597e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1598e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
1599e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
1600e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
1601e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
1602e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1603e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
1604e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
1605e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
1606e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
1607e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1608e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
1609e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
1610e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1611e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
1612e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
1613e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1614e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1615e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
1616e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
1617e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1618e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
16194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
16204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
16224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
16234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
16244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
16254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
16264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
16288ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
16294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
16318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
16328ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
16334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16348ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
16354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
16364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
16374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
16384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
16394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
16414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
16434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
16444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
16454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
16464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
16474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
16484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
16494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16508ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
165148828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16524a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
16538ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16548ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
16558ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
16568ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
16578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
16588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
16598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
16618ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
16628ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
16638ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16648ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
16658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
16668ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
16678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
16688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
16698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
16718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
16728ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
16738ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
16748ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
16758ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
16764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16785e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
16798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale");
16804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
16814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16825e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
16834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
16844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
16854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
16864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
16874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
16884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
16894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
16904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
169108768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
169208768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
169308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
169408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
169508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
16964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
16985e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
16998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
17015e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17025e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
17035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
17058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
17065e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
17075e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
17095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
17105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
17115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
17125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
17135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
17145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
17155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
17165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
17185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
17195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1720155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
17215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
17225e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17231e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
17245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
17255e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
17275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
17285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
17295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
17307d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
1731c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
1732c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1733c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
17348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1735c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1736c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
1737c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
1738c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1739c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1740c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1741c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1742c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1743c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1744c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1745c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1746dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, new ContentValues[]{v1, v2, v3});
1747c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1748c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1749c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
1750c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
1751c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
1752c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
17538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1754c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
1755c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
1756c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1757c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1758c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1759c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1760c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1761c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1762c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
1763c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
1764c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
1765c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
17667d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
17677d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
17687d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
17697d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
17708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
17717d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
17728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_2);
17737d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
17747d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
17757d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
17767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
17777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
17787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
17818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_1.type)
17827d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
17837d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
17847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
17878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_2.type)
17887d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
17897d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
17907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17917d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
17927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
17947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
1795dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri3, new ContentValues[]{v1, v2});
17967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
17977d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
17988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
17997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
18007d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
18017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
18027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
1803dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1804dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test emails with the same domain as primary account are ordered first.
1805dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1806dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    public void testEmailFilterSameDomainAccountOrder() {
1807dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Account account = new Account("tester@email.com", "not_used");
18088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, account);
1809dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@testemail.com");
1810dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@email.com");
1811dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1812dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1813dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account1@email.com");
1814dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1815dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
1816dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, account.name)
1817dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, account.type)
1818dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .build();
1819dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri1, v2, v1);
1820dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1821dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1822dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
1823dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test "default" emails are sorted above emails used last.
1824dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
1825c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterSuperPrimaryOverUsageSort() {
18268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1827dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1828dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1829c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true, true);
1830dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1831dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Update account1 and account 2 to have higher usage.
1832dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1833dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1834dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1835dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1836dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1837dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1838dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1839dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1840dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1841dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1842dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, v3, v1, v2);
1843dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
1844dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
1845c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    /**
1846c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * Test primary emails are sorted below emails used last.
1847c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     *
1848c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * primary may be set without super primary.  Only super primary indicates "default" in the
1849c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * contact ui.
1850c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     */
1851c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterUsageOverPrimarySort() {
18528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
1853c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
1854c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
1855c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true);
1856c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1857c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Update account1 and account 2 to have higher usage.
1858c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1859c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
1860c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
1861c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1862c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
1863c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
1864c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
1865c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
1866c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
1867c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
1868c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        assertStoredValuesOrderly(filterUri, v1, v2, v3);
1869c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    }
1870c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
187146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
187246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
18738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
18744928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
18754928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
1876dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
18778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
18784928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
18794928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
18804928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
18814928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
188246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
188346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
188446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
188546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
188646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
188746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
188846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
188946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
189046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
189146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
189246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
189346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
189446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
189546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
189646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
189746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
189846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
189946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
190046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
190146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
190246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
190346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
190446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
190546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
190646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
190746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
19084928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
190946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1910dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
1911dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId1,
1912dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0
1913dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
1914dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId2,
1915dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 1
1916dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
1917dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
1918dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
1919dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // account3@email.com should be the first.
192046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
192146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
192246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
192346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
1924f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
1925f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
1926f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
1927f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
1928f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
19298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1930f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
1931f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
1932f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
1933f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
1934f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1935f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
1936f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1937f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
1938f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
1939f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
1940f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
1941f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
1942f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
1943f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
1944f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
1945f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1946f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
1947f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1948f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
1949f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
1950f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
1951f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
1952f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1953f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
1954f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
1955f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
1956f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1957f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
1958f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1959f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1960f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
1961f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
1962f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1963f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
1964f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1965f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1966f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1967f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1968f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1969f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
1970f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1971f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
1972f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
1973f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1974f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
1975f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
1976f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1977f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1978f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
1979f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
1980f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1981f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
1982f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
1983f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
1984f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
1985f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
1986f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
1987f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
1988f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
19894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
19908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Alice", "Nextore");
19914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
19928ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
19934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
19948ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
19954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
19964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
19974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
19984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
19994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
20004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
20014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
20024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20038ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
200448828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
200548828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
20064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
20078ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20088ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
20098ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
20108ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
20118ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
20128ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
20138ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20148ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
20158ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
20168ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
20178ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20188ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
20198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
20208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
20218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
20228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
20238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
20248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
20258ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20268ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
20278ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
20288ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
20298ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
20308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
20318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
20324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
20334a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
20348f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testDataContentUriInvisibleQuery() {
20358f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues values = new ContentValues();
20368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final long contactId = createContact(values, "John", "Doe",
20378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
20388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                        StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
20398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri uri = Data.CONTENT_URI.buildUpon().
20418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true").build();
20428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(4, getCount(uri, null, null));
20438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(contactId);
20458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(uri, null, null));
20478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
20488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesQuery() {
20508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
20518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
20528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
20548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
20558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
20578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
20598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
20608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
20618f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
20628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
20648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
20658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
20668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
20678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
20688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
20698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri0 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "");
20718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri0, null, null));
20728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
20748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2);
20758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
20778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2);
20788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale@ac");
20808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2);
20818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "510");
20838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv1, cv2);
20848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "cold");
20868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri5, null, null));
20878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
20898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
20908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri6, null, null));
20918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Contactables.CONTENT_URI;
20938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri7, cv1, cv2);
20948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
20958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesMultipleQuery() {
20978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
20988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
20998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
21008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
21018f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
21028f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "hot@google.com");
21038f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Cold",
21058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamago");
21068f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId2, "eggs@farmers.org");
21078f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
21098f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId3, "518-354-1111");
21108f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId3, "doeadeer@afemaledeer.com");
21118f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21128f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
21138f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21148f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21158f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
21168f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
21178f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
21188f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21198f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
21208f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21218f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21228f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
21238f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
21248f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
21258f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21268f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv3 = new ContentValues();
21278f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21288f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21298f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.DATA, "hot@google.com");
21308f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.TYPE, Email.TYPE_HOME);
21318f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.putNull(Email.LABEL);
21328f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21338f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv4 = new ContentValues();
21348f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Contacts.DISPLAY_NAME, "Cold Tamago");
21358f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.DATA, "eggs@farmers.org");
21378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.TYPE, Email.TYPE_HOME);
21388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.putNull(Email.LABEL);
21398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv5 = new ContentValues();
21418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Contacts.DISPLAY_NAME, "John Doe");
21428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.DATA, "doeadeer@afemaledeer.com");
21448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.TYPE, Email.TYPE_HOME);
21458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.putNull(Email.LABEL);
21468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv6 = new ContentValues();
21488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Contacts.DISPLAY_NAME, "John Doe");
21498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
21508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.DATA, "518-354-1111");
21518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.TYPE, Phone.TYPE_HOME);
21528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.putNull(Phone.LABEL);
21538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
21558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2, cv3);
21578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
21598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2, cv3);
21608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21618f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tam");
21628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2, cv3, cv4);
21638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "518");
21658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv5, cv6);
21668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doe");
21688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri5, cv5, cv6);
21698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "51");
21718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri6, cv1, cv2, cv3, cv5, cv6);
21728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
21748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
21758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri7, null, null));
21768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri8 = Contactables.CONTENT_URI;
21788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri8, cv1, cv2, cv3, cv4, cv5, cv6);
21798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // test VISIBLE_CONTACTS_ONLY boolean parameter
21818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri9 = filterUri6.buildUpon().appendQueryParameter(
21828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                Contactables.VISIBLE_CONTACTS_ONLY, "true").build();
21838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv1, cv2, cv3, cv5, cv6);
21848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // mark Hot Tamale as invisible - cv1, cv2, and cv3 should no longer be in the cursor
21858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(queryContactId(rawContactId));
21868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv5, cv6);
21878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
21888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
21904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
21914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
21924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2193aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2194d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
21954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
21964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
21984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
21994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
22024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
22034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2204aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2205aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
220682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2207aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
2208ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2209ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2210ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
22114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
22124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2213a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
22144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
221548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2216aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2217d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2218aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
221948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
222048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
222148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
222248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
22233b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
22243b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
22258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, nameValues);
222648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
222748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
222882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
222948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2230ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
2231ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
22324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
223348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
22343b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
223548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2236a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
22373b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
22383b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
2239a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
22407ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22417ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
22427ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
22437ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
22447ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22457ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
22467ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
22477ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
22487ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
2249a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2250a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2251a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2252a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
2253a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2254a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2255a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2256a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2257a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2258a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2260a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2261a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2262a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2263a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2264a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
2265a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2266a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2267a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
2268a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
2269a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
2270a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
2271a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
2272a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2273a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
2274a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
2275a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2276a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2277a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2278a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
2279a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2280a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2281a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2282a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2283a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2284a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
22858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2286a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2287a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2288a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2289a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2290a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
2291a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2292a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2293a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
2294a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
2295a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
2296a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
2297a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2298a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
2299a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
2300a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
23014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
23024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23032f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
23042f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
23052f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
23062f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
2307ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
23084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
23092f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
23102f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
23114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Noah", "Tever", "18004664411",
23122f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
2313d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
23144928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
23154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
23164928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
2317aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
2318aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
23194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
23202f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
23212f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
23222f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
23232f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
2324d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
23254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
23269dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
2327aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
2328d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
23294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
23302f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
23312f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
23322f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
23332f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23342f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
23354928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
23362f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23372f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
23382f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23392f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
23402f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23414928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23422f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
23434928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
23442f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23452f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
23462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
23474928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
23482f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
23499dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
23509dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
23519dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
23522f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
23532f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
23542f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
23559dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
23569dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
23579dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Now the 4th contact has a phone number.
23589dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        insertPhoneNumber(rawContactId4, "18004664414");
23599dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
23609dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // Phone only strequent should return 4th contact.
23614928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
23624928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
23634928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
23644928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
23654928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
23664928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
23674928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values4, values3 });
23684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2369ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
23702f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
23714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
23724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
237363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testQueryContactStrequentFrequentOrder() {
237463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare test data
23758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContact(mResolver);
237663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1 = ContentUris.parseId(insertPhoneNumber(rid1, "1"));
237763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1e = ContentUris.parseId(insertEmail(rid1, "1@email.com"));
237863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContact(mResolver);
238063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did2 = ContentUris.parseId(insertPhoneNumber(rid2, "2"));
238163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContact(mResolver);
238363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did3 = ContentUris.parseId(insertPhoneNumber(rid3, "3"));
238463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContact(mResolver);
238663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did4 = ContentUris.parseId(insertPhoneNumber(rid4, "4"));
238763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid5 = RawContactUtil.createRawContact(mResolver);
238963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did5 = ContentUris.parseId(insertPhoneNumber(rid5, "5"));
239063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
23918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid6 = RawContactUtil.createRawContact(mResolver);
239263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did6 = ContentUris.parseId(insertPhoneNumber(rid6, "6"));
239363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
239463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid1 = queryContactId(rid1);
239563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid2 = queryContactId(rid2);
239663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid3 = queryContactId(rid3);
239763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid4 = queryContactId(rid4);
239863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid5 = queryContactId(rid5);
239963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid6 = queryContactId(rid6);
240063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
240163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Make sure they aren't aggregated.
240263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        EvenMoreAsserts.assertUnique(cid1, cid2, cid3, cid4, cid5, cid6);
240363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
240463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare the clock
240563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.install();
240663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
240763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // We check the timestamp in SQL, which doesn't know about the MockClock.  So we need to
240863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // use the  actual (roughly) time.
240963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long nowInMillis = System.currentTimeMillis();
241163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
241263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
241363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
241463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // A year ago...
241663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(oneYearAgoInMillis);
241763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
241863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1, did2);
241963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1);
242063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // 7 days ago...
242263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(sevenDaysAgoInMillis);
242363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3, did4);
242563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3);
242663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
242763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Yesterday...
242863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.setCurrentTimeMillis(yesterdayInMillis);
242963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5, did6);
243163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5);
243263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Contact cid1 again, but it's an email, not a phone call.
243463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1e);
243563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
243663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- The regular frequent, which is contact based.
243763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note because we contacted cid1 yesterday, it's been contacted 3 times, so it comes
243863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // first.
243963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
244063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid1),
244163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid5),
244263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid6),
244363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid3),
244463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid4),
244563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid2));
244663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
244763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- phone only frequent, which is data based.
244863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note this is based on data, and only looks at phone numbers, so the order is different
244963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // now.
245063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI.buildUpon()
245163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "1").build(),
245263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did5),
245363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did6),
245463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did3),
245563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did4),
245663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did1),
245763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did2));
245863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
245963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
246045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
246145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
246245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
246345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
246445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
246545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
246645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
246745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
246845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
246945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
247045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
247145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
247245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
247345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
247445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
2475363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
2476363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
247745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
247845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
247945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
248045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
248145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
248245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
248345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
248445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
248545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
248645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
248745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
248845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
248945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
249045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
249245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
249345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
249445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
249545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
249645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
249745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2498363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2499363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
2500363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2501363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2502363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
2503363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2504363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2505363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
2506363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
2507363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
2508363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
2509363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
2510363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
2511363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
2512363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2513363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
2514363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
2515363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
2516363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
2517363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
251845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
251945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
252080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    public void testQueryContactFrequentExcludingInvisible() {
252180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values1 = new ContentValues();
252280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email1 = "a@acme.com";
252380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
252480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
252580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values2 = new ContentValues();
252680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email2 = "b@acme.com";
252780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid2 = createContact(values2, "Sam", "Times", "18004664412",
252880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
252980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
253080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
253180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
253280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
253380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // First, we have two contacts in frequent.
253480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
253580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
253680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Contact 2 goes invisible.
253780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        markInvisible(cid2);
253880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
253980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Now we have only 1 frequent.
254080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values1});
2541216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2542216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    }
2543216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2544216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    public void testQueryDataUsageStat() {
2545216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        ContentValues values1 = new ContentValues();
2546216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final String email1 = "a@acme.com";
2547216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
2548216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
2549216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2550216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.install();
2551216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(100);
2552216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2553216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2554216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2555216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 1, 100);
2556216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2557216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(111);
2558216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
2559216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2560216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 2, 111);
2561216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2562216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(123);
2563216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
2564216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2565216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 3, 123);
2566216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2567216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeLongText = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2568216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_LONG_TEXT).build();
2569216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2570216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeLongText, "a@acme.com", 2, 111);
2571216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2572216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(200);
2573216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2574216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2575216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
2576216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2577216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 6, 200);
2578216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2579216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeCall = Data.CONTENT_URI.buildUpon().appendQueryParameter(
2580216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_CALL).build();
2581216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
2582216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeCall, "a@acme.com", 3, 200);
258380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    }
258480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
2585ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
25864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
25874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
25884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
25894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
2590aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
2591aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
25924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
25934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
25944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
2595aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
2596aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
25974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2598ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
25994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
26004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
26024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
26034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2605ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
26064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
26074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
26084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
26094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2611ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
26124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
26134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
26144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
26153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
26163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
261736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
261836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
261924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
262024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
262136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
262236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
262324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
262436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
262524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
262624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
262724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
262824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
262924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
263036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
263136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
263236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
263336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
263436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
263536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
263636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
263736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
263836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
263936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
264036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
264124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
264224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
264336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
264436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
264536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
264636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
264724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
264824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
264936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
265036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
265136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
265236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
265324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
265424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
265524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
265624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
265724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
265824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
265924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
266024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
266124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
266236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
266336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
266436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
266536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
266624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
266724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
266824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
266924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
267024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
267124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
267224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
267336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
267436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
267536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
267636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
267724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
267824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
267924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
268024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
268124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
268224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
268324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
268424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
268524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
268636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
268736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
268836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
268924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
269024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
269136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
269236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
269336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
269436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
269536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
269624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
269724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
269836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
269936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
270036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
270136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
270236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
270324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
270424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
270524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
270624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
270724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
270824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
270924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
271024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
271124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
271224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
271324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
271424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
271524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
271636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
271736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
271836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
271936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
272024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
272124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
272324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
272424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
272524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
272624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
272736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
272836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
272936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
273036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
273124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
273224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
273424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
273524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
273724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
273824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
273924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
274024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
274124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
274224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
274324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
274424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
274524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
274624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
274724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
274824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
274924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
275024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
275124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
275224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
275324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
275424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
275524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
275624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
275724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
27586ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
27596ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
27606ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
27616ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27626ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
27638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Domo", "Arigato");
27646ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
27656ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
27666ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
27676ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
27686ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27696ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
27706ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
27716ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
27726ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
27736ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
27746ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
27756ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27766ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
27776ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
27786ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
27796ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
27805d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
278124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
278224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
278324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
278424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
278524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
278624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
278724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
278824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
27895d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
279024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
27915d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
27925d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
279324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
279424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
279524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
279624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
279724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
279824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
279924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
280024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
280124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
280224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
280424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
280524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
280624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
280724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
280824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
280924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
281124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
281224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
281424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
281524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
281624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
281724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
281824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
281924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
282024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
282124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
282224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
282324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
282424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
282524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
282624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
282724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
282824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
282924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
283024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
283124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
283224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
283324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
283424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
283524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
283624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
283724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
283824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
283924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
284024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
284124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
284224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
284324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
284424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
284524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
284624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
284724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
284824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
284924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
285024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
285124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
285324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
285424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
285524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
285624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
285724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
285824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
285924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
286024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
286224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
286324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
286424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
286524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
286624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
286724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
286824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
286924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
287024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
287224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
287324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
287524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
287624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
287724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
287824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
287924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
288024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
288124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
288324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
288424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
288524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
288624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
288724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
288824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
288924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
289024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
289124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
289224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
289324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
2894cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
2895cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
2896cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
2897cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
2898cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
2899cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
2900cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
2901cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2902cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
2903cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
2904cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
2905a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
2906a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
2907a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
2908a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2909a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
2910a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
2911a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
29128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri profileUri = TestUtil.maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI,
29138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account)
2914a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
2915a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
2916a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
2917a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
2918a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
2919a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
2920a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
2921a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
2922a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
292385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
292485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
292585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
292687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
292785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
292885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
292985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
293085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
293185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
293285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
293385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
293487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
293585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
293685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
293785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
293885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
29390a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
294019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
294119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
294219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
294319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
29448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
294519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
294619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
294719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
294819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
294919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
295019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
295119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
295282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
2953aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
2954aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
295582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
2956aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
2957aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
295819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
295919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
296082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
296119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
2962a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
2963a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
296419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
296519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
296619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
296719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
296819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
296982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
29700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
297119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
297219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
297319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2974a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
297519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
297619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
297719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
297819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
297919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
298082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
29810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
298219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
298319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
298419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
2985a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
298619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
298719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
298819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
298919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
299019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
299189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
299289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
299389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
299489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
299589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
29968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
29978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
299889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
299989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
300089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
300189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
300289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
300389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
30043cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
30053cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
30063cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
30083cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
30099d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
30103cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
30113cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
30123cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
30133cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
30143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
30153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
30163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
30173cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
301894021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
30193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
30203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
30213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
30223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
30233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
30243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
30253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
302673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
30273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
30283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
30293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
3030f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
30318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3032f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3033f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3034f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
3035f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3036f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
3037f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3038f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3039f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
30408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3041f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3042f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3043f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3044f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
3045f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3046f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
3047f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3048f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3049f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
30508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3051f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3052f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3053f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
3054f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
3055f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
3056f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
3057f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
3058f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
3059f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
3060f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
3061f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
3062f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
3063f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
3064f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3065f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
30665f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
30675f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
30685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
30695f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30705f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
30715f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
30725f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
30735f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30745f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
30755f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
30765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
30775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
30785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
30805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
30815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
30825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
30845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
30855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
30865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
30885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
30895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
30905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
30925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
30935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
30955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
30965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
30975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
30985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
30995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
31005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
31015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31025f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
31035f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
31045f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
31055f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
31065f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
31075f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
31085f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
31095f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31105f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
31115f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
31125f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
31135f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31145f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
31155f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
31165f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
31175f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31185f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
31195f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
31205f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
31215f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
31225f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
31235f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
31245f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
3125f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
3126f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
3127f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
3128f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
3129f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
3130f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
3131f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3132f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
3133f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
31348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId0 = RawContactUtil.createRawContactWithName(mResolver, "firstName0",
31358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName0");
3136f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
31378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "firstName1",
31388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName1");
3139f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
3140f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
3141f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
31428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "firstName2",
31438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName2");
3144f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
3145f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
3146f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
3147f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3148f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
3149f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
3150f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
3151f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
3152f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
3153f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
3154f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
3155f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
3156f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3157f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
3158f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
3159f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
3160f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
3161f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
3162f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
3163f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
3164f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
3165f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3166f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
3167f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
3168f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
3169f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
3170f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
3171f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
3172f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
3173f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
3174f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3175f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3176f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3177f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
3178f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
3179f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
3180f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
3181f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3182f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3183f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3184f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
31858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "firstName3",
31868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName3");
3187f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
3188f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
3189f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
3190f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
3191f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3192f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3193f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3194f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
319518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
319618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
319718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
319818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
319918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
320018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
320118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
320218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
320318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
320418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
320518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
320618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3207f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
3208f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3209f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
3210f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
3211f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
321218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
321318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
321418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
321518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
321618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
321718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3218f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
3219f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
3220f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
3221f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
3222f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
3223f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
3224f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
3225f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
322618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
322718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
322818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
322918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
323018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
323118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3232f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
323323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
323423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
323523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
323623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
323723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
323823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
323923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
324023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
324123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
324223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
324323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
324423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
3245f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3246f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
324789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
324889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
324989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
3250f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
325189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
325289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
3253f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
32548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
32558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
3256f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
3257f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
3258f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
3259f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
3260f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
326189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
326289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
3263f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
326489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
3265f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
326689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
3267f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
3268f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
3269f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
3270f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
3271f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
3272f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
3273f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
3274f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
3275f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
3276f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
3277f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
32780e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
32790e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
32800e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
32810e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
32820e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
32830e21a867a572679d64d79041eb574d13665178d4Dave Santoro
32840e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
32850e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
32860e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
32870e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
32880e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
328989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
329089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
32914097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
32928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
32934097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
32944097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
32958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
32964097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
329717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
32984097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
32994097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
330067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
33018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
330267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
330367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
330467c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
330567c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
33068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
330717a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
330867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
330967c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
33104097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
33118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
33124097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
33134097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
33144097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
33158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
33164097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33175ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
33184097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
33194097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
33205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
3321a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.ENGLISH);
33228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, null);
33235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
33255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
33265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
33275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
33285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
33295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
33308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
33315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
333455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
333555e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
33365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
33375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
33385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3339a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
33405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3341a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
33445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
33455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
334855e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
334955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
33505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
33515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
33525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3353a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
33545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3355a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
33585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
33595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
33605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
33625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
33635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
33645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
3366a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
33675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
33685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
3369a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
33705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
33725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
3374a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        // "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B"
33755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
33768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
33775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
33805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
33815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
33825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
33835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3384a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3385a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3386a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3387a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
33885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
33905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
33915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
33925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
33935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
33945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
33955dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
33965dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
33975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3398a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3399a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3400a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3401a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
34025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34110f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    public void testJapaneseNameContactInEnglishLocale() {
34120f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // Need Japanese locale data for transliteration
34130f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        if (!hasJapaneseCollator()) {
34140f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            return;
34150f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        }
34160f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContactLocaleUtils.setLocale(Locale.US);
34179aec6b8422f8d153a91a241f1b10d6e48d338bb8Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(null);
34180f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34190f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContentValues values = new ContentValues();
34200f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
34210f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
34229aec6b8422f8d153a91a241f1b10d6e48d338bb8Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
34230f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34240f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
34250f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // en_US should behave same as ja_JP (match on Hiragana and Romaji
34260f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // but not Pinyin)
34270f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
34280f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
34290f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
34300f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    }
34310f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
3433a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3434a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3435a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3436a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
34378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
34385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
34405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
34415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
34428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
34435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
34475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
34485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
34495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
34505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
34515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3452a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3453a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
34545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
34565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
34575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
34595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
34605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
34615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
34625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
34635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
34645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
34655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
3466a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
3467a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
34685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
34705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
34715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
34725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
34735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
34745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
34750f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
34760f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
34770f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // ja_JP should match on Hiragana and Romaji but not Pinyin
34780f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
34790f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
34800f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
34815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
34825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
348325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
34848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
348525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
348625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
34878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
348825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
348925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
34900c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
34910c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
349225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
349325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
349425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
34958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Potato", "Head");
349625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
349725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
349881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
349925abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
350025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
350101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
35028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
350301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3504a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
350501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
350601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
350701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
350801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
350901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
351001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
351101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
351201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
351301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
351401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
351501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
351601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
351701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3518a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
3519a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3520a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
35215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
352201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
352301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
3524a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
3525a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
3526a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
3527a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
3528a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
3529a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
3530a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
3531a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
3532a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
35338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
35345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
35355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
35388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
35395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
35405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
35415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
35435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
35455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
35475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
35485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
35495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
35515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
35535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
35545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
35575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
35585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
35595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
35605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
3561a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "M");
3562a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "M");
35635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
35645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
3567a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
3568a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
3569a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
3570a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
35718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
35725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
35735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
35745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
35765dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35775dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
35785dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
35805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
35815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
35825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
35845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
35855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
35865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
35875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
35885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
3589a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u305F");
3590a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u305F");
35915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
35925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
35935dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
35945dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
3595a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
35960b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
35970b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
3598a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
35990b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
36008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
36015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
36025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
36035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
36055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
36075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36085dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
36095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
36105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
36115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
36125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
36135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
36145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3615a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u4E2D\u56FD\u7535\u4FE1");
3616a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "Z");
3617a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u4E2D\u56FD\u7535\u4FE1");
3618a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "Z");
36195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
362001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
362101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
362231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
36238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
362431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
362531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
362631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
362731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
362831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
362931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
363031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
363131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
363231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
363331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
363431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
363531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
363631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
363731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
363831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
363931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
364031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
364131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
364331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
364431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
364531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
364731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
364831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
364931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
365031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
365131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
365231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
365331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
365431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
365531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
365631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
365731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
365831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
365931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
366031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
366131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
366231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
366331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
366431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
366531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
366631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
366731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
366831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
366931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
3670a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
36710f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
36720f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertEquals(0, getCount(filterUri, null, null));
3673a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
3674a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
3675916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
36768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3677916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3678916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3679916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
3680916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
3681916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3682916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3683916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3684916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
36859c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
3686916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
3687916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3688916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
3689916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
3690916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3691916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3692916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
3693916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
3694916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
3695916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3696916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
3697916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3698916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
36996f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3700916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3701916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3702916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "engineer, [acmecorp]");
3704916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3705916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3706916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3707916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
37088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
3709916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3710916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3711916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
3713916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
3714916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37156f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
3716916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3717916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3718916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
37193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[acme@corp.com]");
3720916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3721916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3722916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3723fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
3724fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
3725fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
3726fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
3727fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
3728fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
3729fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
3730fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
3731fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
3732fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
3733fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
3734fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
3735fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
37363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
37378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
37383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
37393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
37403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
37423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
37433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
37453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
37463716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(SearchSnippetColumns.SNIPPET, "[(860) 555-1234]");
37473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
37503716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
37523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
37543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
37563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
37583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
37603716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
37613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
37623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
37633716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37646f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
37656f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
37666f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
37676f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
37686f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
37696f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
37706f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
37716f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
37726f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
3773916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
37748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3775916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3776916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
3777916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3778916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
3779916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37806f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
3781916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
3782916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
3783916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
378430cc766756461da8d53933f88ea01dd2272a90ebDmitri Plotnikov        values.put(SearchSnippetColumns.SNIPPET, "[Incredible]");
3785916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
3786916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
3787916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
37883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
37898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
37903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
37918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
37923716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
37933716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37943716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
37953716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
37963716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
37973716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
37983716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
37996f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
38006f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("john", true), emptySnippet);
38013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
38048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
38073716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38093716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
38103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
38113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
38123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
38133716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38146f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
38153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
38188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
38213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
38223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
38233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
38243716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
38253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
38263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
38283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
38293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
38303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
38313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38326f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("aperture", true), emptySnippet);
38333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
38368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
38393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
38403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
38423716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
38433716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
38443716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
38453716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38466f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("860", true), emptySnippet);
38473716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38483716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38493716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
38508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38513716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
38523716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
38533716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
38543716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38553716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues emptySnippet = new ContentValues();
38563716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.clear();
38573716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(Contacts._ID, contactId);
38583716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        emptySnippet.put(SearchSnippetColumns.SNIPPET, (String) null);
38593716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
38606f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        assertStoredValues(buildFilterUri("cave", true), emptySnippet);
38613716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
38623716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
3863dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
38648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, "Slinky", "Dog");
3866dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3867dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3868dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3869dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3870dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
3871dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3872dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
3873dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
3874dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3875dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3876dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
3877dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3878dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
3879dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3880dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3881dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
3882dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3883dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
3884dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
3885dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3886dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
3887dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
3888dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
3889d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
3890d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
3891d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
3892d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3893d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
3894d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
3895d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
3896d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
3897d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
3898d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
3899d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
3900d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
3901d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
3902d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
3903d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
3904d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
3905d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
3906d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
39078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3908d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3909d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3910d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
3911d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
3912d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
3913d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
3914d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
3915d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3916d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3917d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
39188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
3919d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
3920d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3921d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
3922d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
392381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
39248c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
39258c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
39268c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
39278c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
3928d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3929d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3930d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
39318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "a", "b");
3932d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3933d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3934d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "c", "d");
3936d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3937d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
3938d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3939d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39400c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39410c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3942d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3943d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
3944d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
3945d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3946d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3947d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
39488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "e", "f");
3949d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3950d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
3951d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "g", "h");
3953d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3954d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
3955d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3956d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39570c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39580c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3959d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3960d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
39610c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
3962d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3963d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3964d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
39658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "i", "j");
3966d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
3967d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
3968d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "k", "l");
3970d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
3971d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
3972d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3973d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
39740c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
39750c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3976d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
3977d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
39780c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
39790c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
3980d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
39813cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
3982d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
3983d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
3984d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
398582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
39868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
39870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
39880a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
39890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
39900a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
39910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
39920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
39930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
39940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
39950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
39960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
39970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
39980a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
39990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
40000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
40010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
40030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
40050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
40070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
40080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40110a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
40120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
40130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
40140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
40150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
40160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
40220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
40230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
40240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
40250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
40260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
40270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
40300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
40310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
40320a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
40330a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
40340a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
40350a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
40360a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
40370a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40380a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
40398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40400a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
40410a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
40420a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40430a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
40440a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40450a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
40460a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
40470a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40490a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
40500a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40510a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
40520a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
40530a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
40540a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
40550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40560a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
40570a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
40580a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
40590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
40608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
40614dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
40624dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
406382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
40644dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40654dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
4066aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4067aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
40684dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40694dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
4070aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
4071d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
40724dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40734dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
4074aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
4075aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
40764dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
40774dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
4078aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
4079aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
40804dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
408182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
408282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
40830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
408482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
40854dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
408682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
40874dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
408882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
40894dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
409082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
40914dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
40924dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
4093bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4094bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4095bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4096bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4097bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
409882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
40990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4100bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4101bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
4102bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
410382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
41048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4105bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4106bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4107bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4108bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4109bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4110bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
411182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
411282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
4113bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4114bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4115aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
4116aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4117aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
4118aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
411982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
4120aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4121aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
412282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4123bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
412482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
412582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4126bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4127bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
41289705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
41299705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
41309705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
41319705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
41329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
41339705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
41349705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
41359705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41369705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41379705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41389705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
41399705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41409705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41419705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41439705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
41449705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
41459705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
41469705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
41479705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
41489705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41499705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41509705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41519705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41529705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41539705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
41549705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
41559705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41569705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41579705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
41589705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
41599705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
41609705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
41619705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
41629705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
41639705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
41649705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
41659705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
41669705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
41679705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
41689705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
41699705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
41709705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
41719705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
417282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
41739705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
417482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4175a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4176a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
4177a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4178093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
41798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4180093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4181093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4182093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4183093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4184093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4185093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
4186093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
4187093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4188093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
4189093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4190093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4191093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
4192093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4193093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4194093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4195093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4196093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
4197093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
4198093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
4199093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4200093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4201093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4202093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4203093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4204093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
4205093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
420682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
42078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4208a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4209a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
4210a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4211a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4212a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4213aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
42145d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4215aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
42165d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4217aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
42185d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4219a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4220a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
4221a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
422282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
422382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4224bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
42254dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42264dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
422782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
422882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
42294dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
423082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
423182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
4232a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
423382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
42344dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
42354dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
42364dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
42373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
42383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
42408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
42413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
42433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
42463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
42473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
42518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
42583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
42638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
42663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
42713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
42768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
42783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
42793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
42823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
42833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
42843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
42853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
42863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
42873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
42883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
42918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
42933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
42943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
42953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
42963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
42973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
42988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
42993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
43013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
43053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
43093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
43123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
43133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
43168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
43233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
43273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
43283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
43293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
43313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
43323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
43333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
43363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
43388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
43403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
43413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
43423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
43443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
43456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
43473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
43483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
43503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
43513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
43523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
43558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
43583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
43633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
43683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
43693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
43706802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
43733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
43746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
43756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
43763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
43776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
43783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
43803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
43813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
43823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
43833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
43843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
43868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
43893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
43903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
43913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
43923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
43943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
43953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
43963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
43973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
43983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
43993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
44003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
44013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
44026802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
44053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
44066802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
44076802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
44083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
44093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
44106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
44113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
44133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
44163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
44183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
44193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
44213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
44223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
44243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
44253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
44263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
44273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
44303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
44323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
44333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
44353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
44373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
44393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
44403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
44423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
44433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
44443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
44453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
44463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
44473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
44483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
44528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
44553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
44563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
44573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
44583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
44593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
44628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
44653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
44673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
44693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
44703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
44713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
44723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
44733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
44743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
44763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
44783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
44793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
44803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
44813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
44823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
44833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
44843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
44853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
44863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
44873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
44883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
44893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
44903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
44913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
44933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(doomedStreamItemId, streamItemIds.get(0));
44943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
44953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
44963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
44978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
44993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
45003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
45023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
45033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
45053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
45073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
45083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
45113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
45123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
45133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
45143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
45153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
45183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
45208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
45223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
45233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
45253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
45263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
45273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
45293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
45303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
45313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
45323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
45333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
45343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
45353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
45363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
45383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
45403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
45413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
45423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
45433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
45443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
45463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
45473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
45483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
45493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
45503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
45533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
45546802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
45556802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
45563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
45573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
45583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
45596802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
45606802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
45616802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
45626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
456387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                EvenMoreAsserts.assertImageRawData(getContext(),
4564c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                        expectedPhotoBytes, mResolver.openInputStream(Uri.parse(photoUri)));
45656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
45663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
45673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
45683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
45693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
45723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
45748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
45773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
45783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
45793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
45803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
45813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
45823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
45843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
45878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
45893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
45903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
45913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
45923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
45933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
45943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
45953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
45963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
45973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
45983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
45993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
46003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
46028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
46133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
46143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
46153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
46173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
46183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
46196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
46203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
46216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
46226802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
46236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
462487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4625c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
46266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
46273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46296802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
46308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
46323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
46333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
46343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
46353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
46363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
46373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
46396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
46406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
46413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
46423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
46433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
46443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
46453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
46466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
46473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
46486802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
46496802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
46506802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
465187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
4652c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
46536802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
46543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
46573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
46598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
46613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
46623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
46633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
46653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
46663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
46673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
46693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
46703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
46713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
46733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
46763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
46798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
46813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
46823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
46843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
46853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
46863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
46883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
46893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
46903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
46923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
46933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
46943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
46953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
46963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
46983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
46993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
47008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
47043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
47053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
47063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
47073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
47083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
47103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
47113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
47133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
47143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
47153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
47163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
47173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
47183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
47193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
47203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
47213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
47248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
47253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
47263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
47273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
47283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
47293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
47306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
47313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
47323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
47333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
47343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
47353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
47363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
47383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
474082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
47418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
474282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
474382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
474482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
474582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
474682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
474782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
474882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
474982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
475082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
475182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
475282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
475382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
475482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
475582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
47563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
47573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
47583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
47593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
47603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
47613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
47626802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
47636802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
47646802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47656802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
47666802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47676802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
47686802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
47696802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
47706802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
47716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
47726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
47736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
47746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
47756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
47766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
47774747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
4778d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
4779d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
4780d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
4781d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
4782d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
4783d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4784d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
4785d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4786d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
4787d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
4788d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
4789d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
4790d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
4791d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
4792d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4793d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
4794d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
4795d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
4796d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
4797d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
4798d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
47994747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
48006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48026802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48036802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48046802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48056802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48066802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
48076802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48086802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
48096802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
48106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
48116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
48126802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
48136802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
48146802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
48156802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48166802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
48176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
48186802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
48196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
48206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
48216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
48224747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
48236802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
48246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
48256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
48266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
48276802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
48286802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
482936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
48308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
483136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
483236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
483336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
483436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
483536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
483636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
483736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
483836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
483936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
484036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
484136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
484236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
484336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
484436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
484536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
484636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
484736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
484836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
484936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
485036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
485136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
485236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
485336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
485436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
485536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
485636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
485736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
485836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
485936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
486036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
486136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
486236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
486336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
486436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
486536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
486636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
486736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
486836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
486936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
487036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
487136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
487236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
487336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
487436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
487536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
487636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
487736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
487836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
487936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
488036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
488136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
48828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
488336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
488436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
488536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
488636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
488736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
488836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
488936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
489036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
489136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
489236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
489336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
489436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
489536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
489636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
489736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
489836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
489936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
490036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
490136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
490236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
490336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
490436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
490536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
49068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
490736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
490836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
490936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
491036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
491136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
491236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
491336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
491436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
491536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
491636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
491736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
491836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
491936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
492036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
492136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
492236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
492336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
492436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
492536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
492636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
492736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
492836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
492936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
493036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
493136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
493236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
493336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
493436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
49358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
493636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
493736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
493836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
493936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
494036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
494136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
494236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
494336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
494436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
494536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
494636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
494736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
494836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
494936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
495036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
495136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
495236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
495336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
495436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
495536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
495636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
495736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
495836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
495936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
496036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
496136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
496236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
496336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
496436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
496536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
496636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
496736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
496836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
496936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
497036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
497136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
49728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
497336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
497436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
497536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
497636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
497736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
497836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
497936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
498136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
498236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
498336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
498436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
498536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
498636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
498736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
498836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
49893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
49903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
49913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
49923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
49933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
49943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
49953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
49963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
49983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
49993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
50006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
50016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
50023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
50033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
500582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
5006bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
5007bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
5008bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
50098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
50104dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
5011bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5012aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
5013aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5014aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
5015aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5016aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
5017aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5018bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5019af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
502082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
50214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
5022bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5023bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
502482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
502582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
50260265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
5027bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
5028bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5029d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
5030d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
5031d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
5032d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
5033d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
5034d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
5035d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5036d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5037d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5038d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
5039d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
50408c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
50418c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
50428c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
50438c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
50448c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
50458c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
50468c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
50478c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
50488c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
50498c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
50508c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
50518c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
50528c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
5053d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
5054d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5055d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
5056d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
5057d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
5058d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
5059d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
5060d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
5061d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
5062d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
5063d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
5064d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
5065d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
5066d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5067d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
5068d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
50699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
50700be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
50718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
50720be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
50730be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50740be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
50750be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
50760be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50770be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
50780be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50790be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50800be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
50810be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50820be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50830be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
50840be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
50850be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50860be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
50870be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
50880be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50890be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
50900be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
50910be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
50920be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50930be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
50940be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
50950be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
50960be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
50970be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
50980db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
50990db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
51000db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
51010db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
51020db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
51030db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
51040db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
51050db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51060db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
51070db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
51080db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51090db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
51100db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
51110db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51120db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51130db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51140db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51150db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
51160db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
51170db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
51180db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
51190db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
51200db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
51210db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
51220db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
51230db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
51240db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
51250db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
51260db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
51270db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
51280db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
51290db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
5130a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
51319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
51329261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
51339261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51349261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
51359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
51369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID, "c0");
51383cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
51393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
51403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
51419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c1 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c1");
51449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
51459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
51469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
51479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
51489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c2 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c2");
51519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
51529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
51539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
51549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c3 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
51568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c3");
51579261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
51589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
51599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
51609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
516162318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
51628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount),
51638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                null, RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
51649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
51659261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
51669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
51676cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
51689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
51699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
51709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
51719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
51729261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
51739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
51749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
51759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
51769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
51779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
51789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
51799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
51809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
51819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
51829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
51839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
51849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
51859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
51866cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
51879261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
51889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
51899261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
51909261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
51919261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
51929261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
51939261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
51949261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
51959261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
51969261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
51979261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
51989261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
51999261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52009261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
52016cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
52029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
52039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
52049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
52059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
52069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
52079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
52089261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
52099261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
52109261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
52119261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
52129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
52139261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
52149261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
52159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
52163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
52179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
521820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
521920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
52208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
522120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
522220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
52235ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
522420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
522520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
522620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
522720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
522820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
522920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
523020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
523120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
523220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
523320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
523420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
523520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
523620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
523720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
523820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
523920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
524020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
524120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
524220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
524320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
524420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
524581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
524620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
524720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
524820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
524920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
525020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
525120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
525220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
525320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
525420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
525520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
525620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
525720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
525820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
525920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
526020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
526120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
526220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
526320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
526420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
526520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
52665ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
526720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
526881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
526970b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
527020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
527120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
52725ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
527320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
527420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
52755ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
527633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
527781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
527833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
527920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
528089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
528189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
528289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
52838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
52848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
528589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
52868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
52878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
528889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
528989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
529089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
529189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
529289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
529389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
529489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
529589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
529689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
529789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
529889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
5299373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
53008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
53015ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
530233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53034dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
530482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5305aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5306aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5307a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
5308a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
530933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
531033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
531182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53124dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
531333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
531433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
531533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
53165870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
531781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
531833b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
5319e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
532033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
532133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
532233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
532333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
532482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
53254dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
5326a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
532781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
5328a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
5329a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5330a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
53318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
53328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
533347fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
533447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
5335a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5336a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5337a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5338a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
5339e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
5340a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
5341a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
5342a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
534320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
53441fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
53455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
53468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5347e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
5348e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5349e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
535082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5351aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5352aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5353e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
5354e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
535582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
5356e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
5357e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5358e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
5359e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
5360e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5361e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
5362e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
5363e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
53645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
53655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
5366e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
53675870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
5368e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5369e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
5370e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
5371e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5372e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
5373e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
5374e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
53755f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
53765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
53775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
53795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
53805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
53828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
53835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
53845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
53865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
53875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
53885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
53895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
53905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
53925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
53935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
53945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
53955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
53965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
53975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
5398e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
53995870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
5400e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
5401e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
54029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
54039ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
54049ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
54059ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
54069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
54079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
54088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2);
54119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54129ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
54138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
54148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
54158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1);
54169ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54179ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
54189ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
54199ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
54209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
54239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
54249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
54259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54279ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54289ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54299ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54309ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
54339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
54349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
54359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
54369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
54389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
54399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
54409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
54419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
54429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
54439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
54459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
54469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
54479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
54499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
54509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
54519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
54529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
54539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
54549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
54568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1 = new Account[] {TestUtil.ACCOUNT_1};
54578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2 = new Account[] {TestUtil.ACCOUNT_2};
54588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1_2 = new Account[] {TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2};
54598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2_1 = new Account[] {TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1};
54609ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54619ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
54629ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54639ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
54649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
54659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
54669ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54679ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
54689ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54699ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
54709ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
54719ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
54729ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
54739ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
54749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
54759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
54769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
54789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54799ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
54809ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
54819ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
54829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
54849ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54859ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
54869ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
54879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
54889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
54909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
54929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
54939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
54949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
54959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
54969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
54979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
54989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
5499627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
550070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
550170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
55028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
550370d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
5504627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
5505743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
550670d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
550770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5508bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
5509743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
5510743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
5511dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
5512dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
551370d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
55148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
5515743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
55168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
5517743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
5518743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
5519743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5520aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5521aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5522743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
5523bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
5524743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
5525627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
552682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
552770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
552870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
552970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
553033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
553133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
553233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5533bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
553433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
553533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
55368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
55378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                readOnlyAccount);
553833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
55398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "john", "doe",
55408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                mAccount);
554133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
554233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
554333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
554433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
554533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
554633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
554733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
554833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
554933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
555033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
555133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
555233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
555333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
555433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
555533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
555633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
555733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5558bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
555933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
556033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
556133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
556233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
556333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
556433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
556533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
556633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
556733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
556833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
556933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
557033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
557133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
557233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
5573c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
5574c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
5575c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
5576c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
5577c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
5578c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
5579c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5580c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
55818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long doomedRawContactId = RawContactUtil.createRawContactWithName(mResolver, doomedAccount);
5582c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
5583c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
5584c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
5585c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
5586c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
5587c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5588c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
55898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long safeRawContactId = RawContactUtil.createRawContactWithName(mResolver, safeAccount);
5590c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
5591c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
5592c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
5593c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
5594c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
5595c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
5596c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5597c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
5598c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
5599c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
5600c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5601c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
5602c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
5603c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
5604c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
5605c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
5606c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
5607c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5608c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
5609c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
5610c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
5611c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
5612c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
5613c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
5614c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
5615cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
56168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
56188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
56198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
5620cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5621cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5622cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5623cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
5624cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
5625cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
5626cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5627cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
5628cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
5629cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
5630cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
563173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
56328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
563373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
563473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
56358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
563673776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
5637e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
563873776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
563973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
564073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
564173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
56425870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
564373776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
564481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
56451fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
56461fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
564761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
56488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5649d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
565073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
56511fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
56521fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
56531fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
56541fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
56551fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
565661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
5657c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
565861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
56591fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
56601fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
56611fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
56621fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
566381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
56641fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
566561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
566661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
566781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56681fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56691fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
567061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
56711fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
567261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
567361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
567461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
56751fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
567681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56771fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56781fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
567961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
56801fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
568161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
56821fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
568381d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
56841fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
56851fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
568661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
56871fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
568861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
56898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
569061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
569161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
569261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
569361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
56941fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
569561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
56961fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
56971fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
56981fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
56991fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
57001fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
57011fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57021fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
570361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
57048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
57051fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
570661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
57071fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
570861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
570961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
571061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
571161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
57125870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
571361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
571481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
571561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
571661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
57171fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
57184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
57199fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
57209fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57219fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57229fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57239fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
57249fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57259fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57269fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57279fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57289fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57299fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
57309fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
57319fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
57329fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57339fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
57349fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
57359fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
57369fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57379fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
57389fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
57399fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
57409fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
57419fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
57429fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
57439fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
57449fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
574560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
574660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
574760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
574860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
574960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
575060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
575160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
575260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
575360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
575460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
575560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
575660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
575760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
575860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
575960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
576060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
576160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
576260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
576360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
576460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
576560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
576660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
576760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
576860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
576960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
577060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
5771074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
5772074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
5773074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
5774074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
57758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
5776f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
5777f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5778f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
5779f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
5780f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5781074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
57823d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
57833d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
5784f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
5785074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
5786074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
5787bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
57888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5789bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
5790bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5791bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
5792bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
5793bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
5794bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
5795bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5796bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
5797bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
5798bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5799bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
5800bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5801bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
5802bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
5803bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
5804bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
5805bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
5806bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5807bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
580887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5809c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithId));
581087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5811c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
5812bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
5813bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
5814ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
58158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
5816f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5817f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5818f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
5819f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
5820f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
5821e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
582287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Check the thumbnail.
582387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
5824f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
582587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki
582687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Then check the display photo.  Note because we only inserted a small photo, but not a
582787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // display photo, this returns the thumbnail image itself, which was compressed at
582887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // the thumnail compression rate, which is why we compare to
582987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL) rather than loadTestPhoto(PhotoSize.DISPLAY_PHOTO)
583087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // here.
583187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // (In other words, loadTestPhoto(PhotoSize.DISPLAY_PHOTO) returns the same photo as
583287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL), except it's compressed at a lower compression rate.)
583387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
583487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                mResolver.openInputStream(photoUri));
5835ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
5836ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
5837732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
58388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
5839f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
5840732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
5841732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
58428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
5843f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
5844732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
5845732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5846732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5847732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5848732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5849732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5850732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5851f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5852f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
5853f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
5854f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
5855f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
5856732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5857f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
5858732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5859732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
5860732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5861732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5862732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
5863732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
5864732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
5865732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5866732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
5867732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
5868732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
5869732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
5870732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
5871732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
5872732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
5873732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
5874732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
5875732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
58768e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
58778e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
58788e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
58798e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
58808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
58818e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58828e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
58838e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
58848e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58858e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
58868e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
58878e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
58888e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
58898e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
58908e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
58918e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5892155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
58938e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
58948e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
58958e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
58968e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
589781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
58988e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
5899f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
59008e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
59018e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
59028e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
59034e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
59047d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
59057d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
59067d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
59077d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
59087d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59097d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
59107d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
59117d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59127d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
59137d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59147d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
59157d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
59167d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
59177d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
59187d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59197d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59207d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59217d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
59227d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59237d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
59247d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
59257d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
59267d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
59277d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
59287d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
59297d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
59307d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
59314e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
59327d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
59334e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
5934f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
59350265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
59367d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
59377d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
5938f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
59398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5940f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5941f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5942f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
5943f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5944f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
594587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5946f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5947f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5948f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5949f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5950f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
59518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5952f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5953f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5954f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5955f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5956f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5957f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
595887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5959f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5960f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5961f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5962f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5963f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
59648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5965f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5966f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
5967f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5968f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
5969f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
5970f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
5971f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
597287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5973f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5974f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5975f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5976f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5977f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
59788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5979f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5980f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
5981f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
5982f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
598387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5984f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5985f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
5986f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
5987f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5988f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
59898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
5990f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
5991f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
5992f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
5993f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
5994f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
5995f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
5996f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
599787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5998f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
5999f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6000f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6001f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6002f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
60038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6004f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6005f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6006f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
6007f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6008f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6009f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
6010f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6011f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6012f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6013f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6014f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
6015f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6016f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6017f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6018f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
6019f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6020f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
6021f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
6022f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6023f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6024f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6025f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
60268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6027f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6028f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6029f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
6030f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
6031f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
6032f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6033f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6034f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6035f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6036f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
6037f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6038f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6039f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6040f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6041f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6042f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
6043f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
6044f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6045f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
6046f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6047f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6048f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
604987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6050f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6051f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6052f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6053f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6054c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
60558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6056f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6057f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6058f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6059c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
6060c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
6061f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6062f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6063c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6064f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6065f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6066c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6067f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6068f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
6069c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
6070c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
6071c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
6072c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
6073c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
6074c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6075c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
6076c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
6077c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6078f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
6079f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6080f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6081f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6082f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
6083c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
6084f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6085f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
608687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6087f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6088f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
608987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6090f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6091f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
6092f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6093f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6094c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
60958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6096f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6097f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6098f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
6099f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
6100f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
6101f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6102f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6103f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6104f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
6105f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6107f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6108f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6109f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6110c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6111c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6112c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
6113c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
6114f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6115f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
6116f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
6117f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6118f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
6119f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6120f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
6121f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
6122f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6123f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
612487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6125f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6126f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
612787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6128f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6129f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
6130f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6131f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6132f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6133c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
6134c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
6135c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
6136c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
6137c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
6138c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
6139c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
6140c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
6141c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
6142c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
6143c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
6144c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
6145c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
6146c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
6147c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
6148c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
6149c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
6150c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6151f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
6152f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6153f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
6154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
6155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
6156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6157f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6158f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
6159f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6160c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
6161f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6162f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6163f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6164f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6165f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
61668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
6167f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
6168f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
6169f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
6170f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
6171f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6172f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
61738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
6174f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
6175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
6176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
6177f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
6181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6182f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
6183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6184f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
6185f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
6186f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
6187f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
6188f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6190f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6191f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
6192f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
61938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver);
6194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
6195f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
6196f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
6197f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
6199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
6200f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
6201f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
6202f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
6203f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6204c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
6205c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
6206c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
62078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId4 = RawContactUtil.createRawContactWithName(mResolver, socialAccount);
6208c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
6209c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
6210c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6211c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6212c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6213c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6214c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6215c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
6216c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6217f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
6218f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
6219f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
6220f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
6222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6224f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
6225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
6227f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
6228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
6229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6231f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
6232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
6233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
6234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
6236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
6238f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
6239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
6240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
6243f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
6244c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6245c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
6246c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6247c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6248c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6249c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
6250f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6251f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6252d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
6253d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6254d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
6255d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6256d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6257ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6258d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6259d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6260d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
6261d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
6262d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
6263d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
6264d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
6265d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
6266d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
6267d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
6268d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
6269d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
6270d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6271d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
6272d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6273d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
6274d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
6275d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
6276d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
6277d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6278d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6279d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6280d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6281d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6282d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6283d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
6284d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
6285d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
6286d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6287d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
6288ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6289d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6290d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6291d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
6292d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6293d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
6294d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6295d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6296d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6297d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
6298d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6299d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
6300d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
6301d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
6302d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
6303d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6304d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
6305d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6306f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
63078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6308f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6309f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6310f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6311f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
6312f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6313f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
6314f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
6315f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6316f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
6317f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
6318f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
6319f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
6320f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6321f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
6322f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
6323f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
6324f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
6325f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
6326f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6327f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6328f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
632987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6330c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6331f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6332f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6333f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
63344e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
63358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
63364e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
63378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
63384e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
633947fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
634047fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
63414e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63424e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
63434e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
63444e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
63454e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63464e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
63474e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
63484e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63494e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
63504e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63514e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
63524e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
63534e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
63544e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63554e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
63564e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
63574e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63584e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
63594e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
63604e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
63614e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63624e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
63634e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
63644e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63654e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
63664e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
63674e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
63684e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
63694e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
63706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
63718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
63726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
63736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
63746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
63766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
63776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
63786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
63806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
63816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
63826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
63836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
63846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
63856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
63866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
63876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
63886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
63896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
63906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
63916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
63926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
63936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
63946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
63956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
63966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
63976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
63986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
63996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
64016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
64026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
64106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
64116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
64146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
64156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
64276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
64306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
64316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
64396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
64426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
64436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
64496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
64516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
64526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
64536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
64546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
64556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
64586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
64596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
64606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
64616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
64626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
64636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
64646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
64656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
64666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
64686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
64696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
64706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
64716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
64728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
64736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
64746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
64766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
64776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
64786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
64796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
64806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
64826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
64836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
64856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
64866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
64876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
64886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
64906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
64916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
64926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
64936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
64946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
64956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
64966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
64976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
64986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
64996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
65006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
65016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
65036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
65046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
65056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
65066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
65076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
65086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
65116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
65126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
65156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
65166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
65196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
65206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
65226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
65236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
65246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
65256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
6526a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    public void testContactSortOrder() {
6527a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + ", "
6528a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY,
6529a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY));
6530a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + ", "
6531a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_ALTERNATIVE,
6532a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE));
6533a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + " DESC, "
6534a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY + " DESC",
6535a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY + " DESC"));
6536a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        String suffix = " COLLATE LOCALIZED DESC";
6537a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + suffix
6538a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + ", " + Contacts.SORT_KEY_ALTERNATIVE + suffix,
6539a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE
6540a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                                                             + suffix));
6541a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
6542a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
6543ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
6544ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
6545ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
6546ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
65478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContact(mResolver);
65488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
65498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "The Abominable", "Snowman");
65508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mike", "Wazowski");
65518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "randall", "boggs");
65528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Boo", null);
65538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mary", null);
65548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Roz", null);
6555ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6556ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
6557ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6558a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                null, null, Contacts.SORT_KEY_PRIMARY);
6559ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
656035997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "", "B", "J", "M", "R", "T");
6561ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
6562ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6563ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6564ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
6565ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
6566ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
6567ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
656835997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", "");
6569ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
6570ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
6571ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6572ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
65731f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    public void testContactCountsWithGermanNames() {
65741f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        if (!hasGermanCollator()) {
65751f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            return;
65761f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
65771f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        ContactLocaleUtils.setLocale(Locale.GERMANY);
65781f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65791f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Uri uri = Contacts.CONTENT_URI.buildUpon()
65801f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                .appendQueryParameter(ContactCounts.ADDRESS_BOOK_INDEX_EXTRAS, "true").build();
65811f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Josef", "Sacher");
65838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Franz", "Schiller");
65848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Eckart", "Steiff");
65858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Klaus", "Seiler");
65868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Lars", "Sultan");
65878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Heidi", "Rilke");
65888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Suse", "Thomas");
65891f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65901f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        Cursor cursor = mResolver.query(uri,
65911f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                new String[]{Contacts.DISPLAY_NAME},
65921f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                null, null, Contacts.SORT_KEY_ALTERNATIVE);
65931f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
65941f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterValues(cursor, "R", "S", "Sch", "St", "T");
65951f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        assertFirstLetterCounts(cursor,   1,   3,     1,    1,   1);
65961f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        cursor.close();
65971f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
65981f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
6599ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
6600ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
6601ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getStringArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
6602ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6603ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6604ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6605ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
6606ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
6607ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                .getIntArray(ContactCounts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
6608ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
6609ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
6610ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
6611f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
6612f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
6613f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
6614f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
6615f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
6616f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
6617f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
6618f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
6619f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
6620f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
6621f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
6622f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
6623f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6624f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6625f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
6626f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
6627f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
6628f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
6629f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6630f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6631f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
6632f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
6633f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
6634f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
6635f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
6636f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
6637f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
6638f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
6639f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
66405fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
66415fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
66425fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
66435fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
66445fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
66455fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
66465fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
66475fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
66485fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
66495fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
66505fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
66515fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
66525fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
6653f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
6654f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
6655e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
6656e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
6657e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
6658e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
6659e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6660e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
6661e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
6662e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6663e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6664e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6665e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6666e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6667e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
6668e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
6669e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
6670e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
6671e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
6672e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
6673e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
6674e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
6675e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
66768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri insertUri = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI,
66778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                blue);
6678e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
6679e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
6680e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
6681e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
6682e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
6683e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
6684e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
6685e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
66863826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
66873826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
66883826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
66893826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
66903826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
66918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
66923826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
66933826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
66943826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
66953826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
66963826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
66973826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
66983826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
66993826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        mActor.setAccounts(new Account[]{TestUtil.ACCOUNT_1});
67018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{TestUtil.ACCOUNT_1});
67023826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
6703bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
67043826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
67053826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
67063826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
67073826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
67083826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
670909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
671009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
671109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
671209c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
67133826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
671409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
671509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
671609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
6717b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
6718743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
6719b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
6720b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
6721b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
6722b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
6723b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
6724b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
6725b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
6726b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
6727b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
6728b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
6729b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
6730b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
673142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
673242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
673342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
673442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
673542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
673642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
673742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
673842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
673942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
674042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
674142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
674242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
674342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
674442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
674542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
674642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
674742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
674842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
674942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
675042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
675142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
675242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
675342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
675442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
675542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
67568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount,
67578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "4:12");
67588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
675942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
67608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccount,
67618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "3:4%121");
67628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doh");
676342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
676442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
676542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
676642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
676742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
676842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
676942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
677042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
677142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
677242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
677342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
677442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
677542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
677642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
677742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
677842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
677942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
678042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
678142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
678242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
678342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
678442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
678542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
678642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
678742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
678842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
678942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
679042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
679242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
679342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
679442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
679542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
679642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
679742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
679842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
679942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
680042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
680142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
680242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
680342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
680442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
680542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
680642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
680742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
680842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
680942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
681042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
681142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
681242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
681342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
681442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
681524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
681624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
681724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
681824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
681924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
682024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
682124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
682224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
682324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
682424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
682542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
682642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
682742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
682842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
682942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
683042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
683142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
683242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
683342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
683442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
683542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
683642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
683742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
683842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
683942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
684042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
684242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
684342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
684442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
684542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
684642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
684742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
684842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
684942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
685042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
685142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
685224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
685324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
685424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
685542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
685642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
685742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
685842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
685942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
686042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
686142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
686242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
686342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
686442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
686542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
686642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
686742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
686842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
686942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
6870dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
6871dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6872dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6873dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
6874dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
68758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
68768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
68778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, null);
6878dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6879dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6880dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6881dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6882dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6883dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6884dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6885dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6886dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6887dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6888dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6889dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
6890dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6891dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6892dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
6893dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
6894dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6895dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6896dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6897dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6898dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6899dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6900dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
69018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
69028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount);
69048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null);
6907dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6908dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6909dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6910dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6911dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
6912dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6913dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
6914dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6915dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6916dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6917dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6918dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6919dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
6920dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
6921dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
6922dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
6923dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
6924dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
69258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
69278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
69288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo, RawContacts.STARRED, "1");
69298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
69308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null, RawContacts.STARRED, "1");
69318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r7 = RawContactUtil.createRawContact(mResolver, null);
6932dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6933dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6934dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6935dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6936dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6937dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
6938dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
6939dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6940dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6941dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6942dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6943dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6944dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6945dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6946dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6947dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6948dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6949dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
6950dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6951dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6952dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6953dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6954dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6955dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6956dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6957dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6958dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6959dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6960dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6961dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6962dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
6963dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
6964dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
6965dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6966dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
6967dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
6968dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6969dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6970dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
6971dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6972dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6973dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
6974dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
6975dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
6976dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
6977dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
6978dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
6979dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
6980dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
6981dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6982dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
6983dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6984dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
6985dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
6986dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6987dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
6988dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
6989dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
6990dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
6991dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
6992dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
6993dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
6994dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
6995dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
6996dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
6997dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
6998dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
6999dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7000dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
70018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
70028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
70038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7004dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7005dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7006dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7007dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7008dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7009dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7010dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7011dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7012dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7013dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7014dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7015dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7016dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7017dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7018dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7019dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7020dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7021dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7022dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7023dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
7024dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
7025dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7026dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7027dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7028dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7029dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7030dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7031dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7032dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7033dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7034dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7035dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7036dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7037dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7038dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7039dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7040dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7041dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7042dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7043dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7044dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7045e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
7046dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
7047dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7048dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
7049dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
7050dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7051dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7052dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7053dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7054dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7055dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7056dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7057dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7058dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7059dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7060dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7061dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7062dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7063dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7064dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7065dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
7066dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7067dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7068dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7069dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7070dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7071dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
7072dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7073dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7074dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7075dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
70768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
70778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
70788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7079dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7080dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7081dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7082dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7084dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
7085dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7086dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
7087dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
7088dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
7089dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
7090dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7091dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7092dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7093dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7094dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7095dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7096dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7097dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7098dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7099dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7100dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7101dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7102dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7103dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7104dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
7105dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
7106dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
7107dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7108dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7109dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7110dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
7111dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7112dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7113dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7114dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
7115dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
7116dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
7117dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7118dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7119dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7120dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7121dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
7122dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7123dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7124dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
7125dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7126dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7127dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7128dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7129dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7130dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7131dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
7132dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
7133dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
7134dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7135dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7136dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7137dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7138dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7139dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7140dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
714197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
71428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
714397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
714497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
714597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
714697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
714797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
714897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
714997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
715097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
715197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
715297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
715397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
715497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
715597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
715697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
715797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
71588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
715997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
716097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
716197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
716297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
716397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
716497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
716597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
716697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
716797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
716897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
716997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
717097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
717197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
717297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
717397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
717497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
717597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
71768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
717797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
717897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
717997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
71808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
718197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
718297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
718397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
718497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
718597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
718697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
718797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
718897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
718997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
719097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
719197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
719297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
719397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
719497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
719597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
719697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
71977a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
71987a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
71997a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
72007a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72017a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
72027a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
720317a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
72047a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72057a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72067a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72077a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72087a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72097a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72107a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72117a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72127a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72137a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
72147a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
72157a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
72167a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
72177a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
72187a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
72197a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
72207a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
72217a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
72227a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
72237a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
722455e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
72257a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
72267a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
72277a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
72287a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
72297a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
72307a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
72317a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
72327a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
72337a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
72347a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
72357a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
7236084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    public void testBuildSingleRowResult() {
7237084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7238084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b"},
7239084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7240084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7241084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2}
7242084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7243084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7244084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7245084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b", "a", "b"},
7246084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7247084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7248084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2, 1, 2}
7249084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7250084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7251084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7252084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                null, // all columns
7253084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7254084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7255084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2}
7256084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7257084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7258084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7259084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            // Access non-existent column
7260084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            ContactsProvider2.buildSingleRowResult(new String[] {"a"}, new String[] {"b"},
7261084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                    new Object[] {1});
7262084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            fail();
7263084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } catch (IllegalArgumentException expected) {
7264084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7265084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7266084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7267084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    private void checkBuildSingleRowResult(String[] projection, String[] availableColumns,
7268084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            Object[] data, Integer[] expectedValues) {
7269084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        final Cursor c = ContactsProvider2.buildSingleRowResult(projection, availableColumns, data);
7270084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7271084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertTrue(c.moveToFirst());
7272084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(1, c.getCount());
7273084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(expectedValues.length, c.getColumnCount());
7274084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7275084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            for (int i = 0; i < expectedValues.length; i++) {
7276084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                assertEquals("column " + i, expectedValues[i], (Integer) c.getInt(i));
7277084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            }
7278084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } finally {
7279084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            c.close();
7280084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7281084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7282084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7283dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    public void testDataUsageFeedbackAndDelete() {
7284dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7285dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.install();
7286dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7287dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long startTime = sMockClock.currentTimeMillis();
7288dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
72898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "contact", "a");
7290dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1a = ContentUris.parseId(insertEmail(rid1, "email_1_a@email.com"));
7291dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1b = ContentUris.parseId(insertEmail(rid1, "email_1_b@email.com"));
7292dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1p = ContentUris.parseId(insertPhoneNumber(rid1, "555-555-5555"));
7293dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
72948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "contact", "b");
7295dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2a = ContentUris.parseId(insertEmail(rid2, "email_2_a@email.com"));
7296dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2p = ContentUris.parseId(insertPhoneNumber(rid2, "555-555-5556"));
7297dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7298dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Aggregate 1 and 2
7299dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rid1, rid2);
7300dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContactWithName(mResolver, "contact", "c");
7302dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3a = ContentUris.parseId(insertEmail(rid3, "email_3@email.com"));
7303dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3p = ContentUris.parseId(insertPhoneNumber(rid3, "555-3333"));
7304dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
73058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContactWithName(mResolver, "contact", "d");
7306dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did4p = ContentUris.parseId(insertPhoneNumber(rid4, "555-4444"));
7307dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7308dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid1 = queryContactId(rid1);
7309dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid3 = queryContactId(rid3);
7310dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid4 = queryContactId(rid4);
7311dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7312dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Make sure 1+2, 3 and 4 aren't aggregated
7313dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid3);
7314dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid4);
7315dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid3, cid4);
7316dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7317dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime
7318dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7319a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // First, there's no frequent.  (We use strequent here only because frequent is hidden
7320a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // and may be removed someday.)
7321a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7322a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7323dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 1. touch data 1a
7324dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a);
7325a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7326dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, there's a single frequent.  (contact 1)
7327a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(1, Contacts.CONTENT_STREQUENT_URI, null, null);
7328a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7329dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 1
7330dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7331dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7332dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 1a, 2a and 3a
7333dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a, did2a, did3a);
7334dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7335dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, contact 1 and 3 are in frequent.
7336dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7337dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7338dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 2
7339dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7340dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7341dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 2p (call)
7342dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did2p);
7343dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7344dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // There're still two frequent.
7345dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7346dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7347dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 3
7348dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7349dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7350dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 3. touch data 2p and 3p (short text)
7351dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, did2p, did3p);
7352dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7353dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's check the tables.
7354dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7355dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Fist, check the data_usage_stat table, which has no public URI.
7356dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7357dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.USAGE_TYPE_INT +
7358dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.TIMES_USED +
7359dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.LAST_TIME_USED +
7360dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7361dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did1a,
7362dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7363dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7364dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 2,
7365dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7366dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7367dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2a,
7368dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7369dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7370dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7371dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7372dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7373dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3a,
7374dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7375dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7376dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7377dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7378dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7379dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7380dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7381dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_CALL,
7382dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7383dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 2
7384dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7385dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7386dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7387dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7388dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7389dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7390dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7391dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3p,
7392dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7393dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7394dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7395dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7396dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7397dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7398dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7399dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Next, check the raw_contacts table
7400dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
7401dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid1,
7402dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7403dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 1
7404dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7405dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid2,
7406dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 3,
7407dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7408dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7409dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid3,
7410dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7411dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7412dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7413dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid4,
7414dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0,
7415dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, null // 4 wasn't touched.
7416dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7417dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7418dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7419dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Lastly, check the contacts table.
7420dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7421dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Note contact1.TIMES_CONTACTED = 4, even though raw_contact1.TIMES_CONTACTED +
7422dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // raw_contact1.TIMES_CONTACTED = 5, because in test 2, data 1a and data 2a were touched
7423dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // at once.
7424dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
7425dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid1,
7426dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 4,
7427dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7428dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7429dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid3,
7430dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 2,
7431dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7432dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7433dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid4,
7434dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 0,
7435dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, 0 // For contacts, the default is 0, not null.
7436dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7437dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7438a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7439dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's test the delete too.
7440b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7441a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7442a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Now there's no frequent.
7443a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7444a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7445dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // No rows in the stats table.
7446dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7447dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7448dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                new ContentValues[0]);
7449dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7450a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // The following values should all be 0 or null.
7451a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
7452a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.LAST_TIME_CONTACTED + ">0", null);
7453a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
7454a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.LAST_TIME_CONTACTED + ">0", null);
7455a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7456a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Calling it when there's no usage stats will still return a positive value.
7457b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7458a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki    }
7459a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
74608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /*******************************************************
74618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Delta api tests.
74628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
74638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_hasDeleteLog() {
74648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
74658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long start = sMockClock.currentTimeMillis();
74668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
74678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, start);
74688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up. Must also remove raw contact.
74708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
74718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
74728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_marksRawContactsForDeletion() {
74748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
74758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        String[] projection = new String[]{ContactsContract.RawContacts.DIRTY,
74778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.RawContacts.DELETED};
74788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        List<String[]> records = RawContactUtil.queryByContactId(mResolver, ids.mContactId,
74798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                projection);
74808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] arr : records) {
74818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[0]);
74828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[1]);
74838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
74848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
74868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
74878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
74888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactUpdate_updatesContactUpdatedTimestamp() {
74908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
74918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
74928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
74948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
74968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.Contacts.STARRED, 1);
74978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
74988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
74998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.update(mResolver, ids.mContactId, values);
75008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    // This implicitly tests the Contact create case.
75098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactCreate_updatesContactUpdatedTimestamp() {
75108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long startTime = System.currentTimeMillis();
75118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
75138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long lastUpdated = getContactLastUpdatedTimestampByRawContactId(mResolver, rawContactId);
75148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(lastUpdated > startTime);
75168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, rawContactId, true);
75198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
75228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
75278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.RawContacts.STARRED, 1);
75288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.update(mResolver, ids.mRawContactId, values);
75298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactPsuedoDelete_hasDeleteLogForContact() {
75388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, false);
75438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
75458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // clean up
75478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactDelete_hasDeleteLogForContact() {
75518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
75588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // already clean
75608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long getContactLastUpdatedTimestampByRawContactId(ContentResolver resolver,
75638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            long rawContactId) {
75648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long contactId = RawContactUtil.queryContactIdByRawContactId(mResolver, rawContactId);
75658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
75668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
75688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataInsert_updatesContactLastUpdatedTimestamp() {
75718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        insertPhoneNumberAndReturnDataId(ids.mRawContactId);
75778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
75828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
75838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
75848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataDelete_updatesContactLastUpdatedTimestamp() {
75868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
75878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
75888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
75908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
75948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.delete(mResolver, dataId);
75958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
75978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
75988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
75998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataUpdate_updatesContactLastUpdatedTimestamp() {
76048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
76068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
76088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
76128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
76138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "555-5555");
76148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.update(mResolver, dataId, values);
76158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
76178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
76188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
76208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
76218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long insertPhoneNumberAndReturnDataId(long rawContactId) {
76248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = insertPhoneNumber(rawContactId, "1-800-GOOG-411");
76258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContentUris.parseId(uri);
76268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsDelete_isUnsupported() {
76298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, URI);
76318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = ContentUris.withAppendedId(URI, 1L);
76338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, uri);
76348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsInsert_isUnsupported() {
76378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
76388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertInsertIsUnsupported(mResolver, URI);
76398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsByContactId() {
76438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
76448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND,
76468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
76478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsAll() {
76508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final int numDeletes = 10;
76518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Since we cannot clean out delete log from previous tests, we need to account for that
76538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // by querying for the count first.
76548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long startCount = DeletedContactUtil.getCount(mResolver);
76558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (int i = 0; i < numDeletes; i++) {
76578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertContactCreateDelete();
76588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
76598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long endCount = DeletedContactUtil.getCount(mResolver);
76618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(numDeletes, endCount - startCount);
76638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsSinceTimestamp() {
76668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
76678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Before
76698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> beforeIds = new HashSet<Long>();
76708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
76718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
76728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long start = sMockClock.currentTimeMillis();
76748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // After
76768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> afterIds = new HashSet<Long>();
76778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
76808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final String[] projection = new String[]{
76828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_ID,
76838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
76848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        };
76858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final List<String[]> records = DeletedContactUtil.querySinceTimestamp(mResolver, projection,
76868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                start);
76878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] record : records) {
76888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check ids to make sure we only have the ones that came after the time.
76898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            final long contactId = Long.parseLong(record[0]);
76908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertFalse(beforeIds.contains(contactId));
76918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(afterIds.contains(contactId));
76928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check times to make sure they came after
76948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(Long.parseLong(record[1]) > start);
76958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
76968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
76978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
76988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
76998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Create a contact. Assert it's not present in the delete log. Delete it.
77008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * And assert that the contact record is no longer present.
77018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     *
77028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * @return The contact id and raw contact id that was created.
77038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
77048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private DatabaseAsserts.ContactIdPair assertContactCreateDelete() {
77058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
77068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(CommonDatabaseUtils.NOT_FOUND,
77088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
77098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
77118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.delete(mResolver, ids.mContactId);
77128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertFalse(ContactUtil.recordExistsForContactId(mResolver, ids.mContactId));
77148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ids;
77168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
77178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
77188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * End delta api tests.
77198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     ******************************************************/
77208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
77218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
7722dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
77238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Cursor c = mResolver.query(TestUtil.maybeAddAccountQueryParameters(Data.CONTENT_URI,
77248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account),
7725dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
7726dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
7727dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
7728dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
7729dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7730dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
773142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
773242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
7733bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
773442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
773542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
7736bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
7737bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
7738bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
7739bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
7740bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
7741bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
7742bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
774342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
7744bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
7745bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
774642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
774742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
774842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
774942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
775042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
775142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
7752f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
7753f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
7754f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
7755f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
7756f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
77574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
77584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
7759aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
776024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
776124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
776224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
776324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
776424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
776524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
776624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
776748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
776824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
776948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
777048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
777148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
777248786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
7773aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
777448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
7775aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
77768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
777748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
777848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
777948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
778024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
778124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
778224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
778324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
778424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
77858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
778624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
778724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
778824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
778948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
7790aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
779124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
779224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
779324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
779424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
779524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
779624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
779724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
77984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
77994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
78004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
78014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
780224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
780324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
780424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
780524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
780624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
78074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
78084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
78094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
78104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
78119dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
78129dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
78139dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
78149dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
78159dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
78169dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
78174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
7818aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
78195d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
78204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
78214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
78224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
78234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
782424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
782548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
78264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
78274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
782824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
782924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
783024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
783124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
783224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
783324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
783424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
783524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
783624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
783724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
783824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
783924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
784024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
784124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
784224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
784324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
784424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
784524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
784624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
784724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
784824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
784924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
785024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
785124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
785224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
785324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
785424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
785524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
78564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
78574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
78584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
78594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
78604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
78614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
78624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
78634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
78644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
78654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
78664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
78674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
78684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
78694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
78704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
78714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
78724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
78734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
78744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
78754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
78764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
78774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
78784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
78794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
78804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
78814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
78824928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
78834928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
78844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
78854928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
78864928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
78874928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
78884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
78894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
78904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
78914928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
7892dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(0, updateDataUsageFeedback(usageType, dataId));
78934928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
78944928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
78954928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
78964928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
7897dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7898dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    private void updateDataUsageFeedback(String usageType, Uri resultUri) {
7899dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final long id = ContentUris.parseId(resultUri);
7900dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final boolean successful = updateDataUsageFeedback(usageType, id) > 0;
7901dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertTrue(successful);
7902dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
7903dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
7904dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    private int updateDataUsageFeedback(String usageType, long... ids) {
7905dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final StringBuilder idList = new StringBuilder();
7906dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        for (long id : ids) {
7907dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            if (idList.length() > 0) idList.append(",");
7908dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            idList.append(id);
7909dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        }
7910dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        return mResolver.update(DataUsageFeedback.FEEDBACK_URI.buildUpon()
7911dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendPath(idList.toString())
7912dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
7913dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .build(), new ContentValues(), null, null);
7914dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    }
7915a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
7916a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasChineseCollator() {
7917a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
7918a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
7919a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.CHINA)) {
7920a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
7921a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
7922a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
7923a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
7924a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
7925a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
7926a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasJapaneseCollator() {
7927a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
7928a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
7929a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.JAPAN)) {
7930a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
7931a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
7932a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
7933a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
7934a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
79351f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
79361f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    private boolean hasGermanCollator() {
79371f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
79381f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        for (int i = 0; i < locale.length; i++) {
79391f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            if (locale[i].equals(Locale.GERMANY)) {
79401f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                return true;
79411f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            }
79421f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
79431f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        return false;
79441f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
7945d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
7946