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;
22a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport android.content.ContentProvider;
23d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderOperation;
24d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikovimport android.content.ContentProviderResult;
258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport android.content.ContentResolver;
26d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentUris;
27d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.content.ContentValues;
289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.content.Entity;
2933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.content.EntityIterator;
30a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport android.content.pm.UserInfo;
3142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport android.content.res.AssetFileDescriptor;
32d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.database.Cursor;
339701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onukiimport android.database.MatrixCursor;
3496062013ec40d4b60dd162a6e4a7146690247a3eYorke Leeimport android.database.sqlite.SQLiteDatabase;
35d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.net.Uri;
36c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoroimport android.os.AsyncTask;
37a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport android.os.UserManager;
38a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport android.provider.CallLog.Calls;
39a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport android.provider.CallLog;
40c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract;
41d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.provider.ContactsContract.AggregationExceptions;
42e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Callable;
43216c434537d05a691add4e22ba3a9d958c976c1eYorke Leeimport android.provider.ContactsContract.CommonDataKinds.Contactables;
44dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
45dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
46dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Im;
47dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Organization;
48dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Phone;
49dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Photo;
50e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
51dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
52dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
53c70dc0e38ff82c6e6d6b7458637c54fbdf446aacDmitri Plotnikovimport android.provider.ContactsContract.Contacts;
549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintanaimport android.provider.ContactsContract.Data;
5546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawaimport android.provider.ContactsContract.DataUsageFeedback;
56dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.ContactsContract.Directory;
575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.DisplayNameSources;
58f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.DisplayPhoto;
597a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikovimport android.provider.ContactsContract.FullNameStyle;
603cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikovimport android.provider.ContactsContract.Groups;
614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikovimport android.provider.ContactsContract.PhoneLookup;
625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport android.provider.ContactsContract.PhoneticNameStyle;
6381fea08280784b319b936a3506788d595c6ce2adYorke Leeimport android.provider.ContactsContract.PinnedPositions;
6424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoroimport android.provider.ContactsContract.Profile;
6509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikovimport android.provider.ContactsContract.ProviderStatus;
6633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikovimport android.provider.ContactsContract.RawContacts;
6762318e1ea8306142a10526534b7d83560ecf5b3aFred Quintanaimport android.provider.ContactsContract.RawContactsEntity;
6854b97025256764a01f927792e64de8bf369e12f1Yorke Leeimport android.provider.ContactsContract.SearchSnippets;
6989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikovimport android.provider.ContactsContract.Settings;
7082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikovimport android.provider.ContactsContract.StatusUpdates;
713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport android.provider.ContactsContract.StreamItemPhotos;
72f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.StreamItems;
73dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikovimport android.provider.OpenableColumns;
747d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekhimport android.test.MoreAsserts;
75d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovimport android.test.suitebuilder.annotation.LargeTest;
76f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.text.TextUtils;
7738210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki
7838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.internal.util.ArrayUtils;
79a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Leeimport com.android.providers.contacts.CallLogProviderTest.TestCallLogProvider;
809701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onukiimport com.android.providers.contacts.ContactsActor.AlteringUserContext;
819701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onukiimport com.android.providers.contacts.ContactsActor.MockUserManager;
8238210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.AggregationExceptionColumns;
83a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.ContactsColumns;
8438210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DataUsageStatColumns;
8538210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.DbProperties;
8638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.PresenceColumns;
87a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shraunerimport com.android.providers.contacts.ContactsDatabaseHelper.RawContactsColumns;
8838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables;
898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.CommonDatabaseUtils;
908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.ContactUtil;
918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DataUtil;
928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DatabaseAsserts;
938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.DeletedContactUtil;
948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.RawContactUtil;
958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport com.android.providers.contacts.testutil.TestUtil;
9638210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.tests.R;
9796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
9838210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Lists;
9938210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.google.android.collect.Sets;
100d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
10142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.FileInputStream;
10242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmannimport java.io.IOException;
103f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.OutputStream;
1045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.text.Collator;
1053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.ArrayList;
1065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Arrays;
1078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Chengimport java.util.HashSet;
1083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmannimport java.util.List;
1095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikovimport java.util.Locale;
1109ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onukiimport java.util.Set;
1115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
112d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov/**
113d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Unit tests for {@link ContactsProvider2}.
114d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov *
115d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * Run the test like this:
116d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * <code>
11723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki   adb shell am instrument -e class com.android.providers.contacts.ContactsProvider2Test -w \
11823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki           com.android.providers.contacts.tests/android.test.InstrumentationTestRunner
119d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov * </code>
120d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov */
121d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov@LargeTest
122d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikovpublic class ContactsProvider2Test extends BaseContactsProvider2Test {
123d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
1248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private static final String TAG = ContactsProvider2Test.class.getSimpleName();
12547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov
126dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsProjection() {
127dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_URI, new String[]{
128dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
129dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
130dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
131dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
132dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
133dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
134dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
135dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
136a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
137a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
138a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
139a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
140dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
141dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
142dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
14381fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
1449273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
145dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
146dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
147f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
1483d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
1493d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
150dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
151dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
152dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
15324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
154dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
155dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
156dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
157dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
158dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
159dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
160dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
161dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
162dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
1638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
164dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
165dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
166dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
16763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentProjection() {
16863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI, new String[]{
16963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
17063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
17163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
17263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
17363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
17463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
17563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
17663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
177a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
178a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
179a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
180a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
18163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
18263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
18363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
18481fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
1859273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
18663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
18763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
18863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
18963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
19063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
19163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
19263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
19363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
19463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
19563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
19663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
19763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
19863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
19963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
20063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
20163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
20263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
20363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
2048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
20563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
20663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
20763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
20863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
20963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
21063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testContactsStrequentPhoneOnlyProjection() {
21163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertProjection(Contacts.CONTENT_STREQUENT_URI.buildUpon()
21263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build(),
21363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                new String[] {
21463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts._ID,
21563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_PRIMARY,
21663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_ALTERNATIVE,
21763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.DISPLAY_NAME_SOURCE,
21863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME,
21963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHONETIC_NAME_STYLE,
22063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_PRIMARY,
22163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SORT_KEY_ALTERNATIVE,
222a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
223a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
224a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
225a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
22663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LAST_TIME_CONTACTED,
22763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.TIMES_CONTACTED,
22863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.STARRED,
22981fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
2309273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
23163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IN_VISIBLE_GROUP,
23263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_ID,
23363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_FILE_ID,
23463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_URI,
23563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.PHOTO_THUMBNAIL_URI,
23663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CUSTOM_RINGTONE,
23763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.HAS_PHONE_NUMBER,
23863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.SEND_TO_VOICEMAIL,
23963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.IS_USER_PROFILE,
24063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.LOOKUP_KEY,
24163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.NAME_RAW_CONTACT_ID,
24263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_PRESENCE,
24363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_CHAT_CAPABILITY,
24463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS,
24563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_TIMESTAMP,
24663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_RES_PACKAGE,
24763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_LABEL,
24863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Contacts.CONTACT_STATUS_ICON,
2498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
25063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.TIMES_USED,
25163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                DataUsageStatColumns.LAST_TIME_USED,
25263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.NUMBER,
25363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.TYPE,
25463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                Phone.LABEL,
255f6de5a9d1418b0d7f4119d4204818ab3a0fe4fa2Yorke Lee                Phone.IS_SUPER_PRIMARY,
256a89aa7533a14b143b55bf4a29d284152ab9278a5Yorke Lee                Phone.CONTACT_ID
25763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        });
25863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
25963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
260dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testContactsWithSnippetProjection() {
261dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Contacts.CONTENT_FILTER_URI.buildUpon().appendPath("nothing").build(),
262dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
263dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
264dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
265dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
266dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
267dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
268dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
269dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
270dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
271a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
272a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
273a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
274a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
275dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
276dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
277dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
27881fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
2799273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
280dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
281dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
282f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
2833d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
2843d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
285dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
286dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
287dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
28824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
289dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
290dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
291dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
292dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
293dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
294dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
295dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
296dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
297dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
2988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
29954b97025256764a01f927792e64de8bf369e12f1Yorke Lee                SearchSnippets.SNIPPET,
300dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
301dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
302dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
303dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawContactsProjection() {
304dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContacts.CONTENT_URI, new String[]{
305dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
306dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
307dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
308dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
30943368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
31043368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
311dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
312dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
31324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
314dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
315dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
316dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_PRIMARY,
317dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_ALTERNATIVE,
318dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DISPLAY_NAME_SOURCE,
319dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME,
320dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.PHONETIC_NAME_STYLE,
321dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
322dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_PRIMARY,
323dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SORT_KEY_ALTERNATIVE,
324a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_PRIMARY,
325a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
326a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
327a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                RawContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
328dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.TIMES_CONTACTED,
329dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.LAST_TIME_CONTACTED,
330dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CUSTOM_RINGTONE,
331dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SEND_TO_VOICEMAIL,
332dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
33381fea08280784b319b936a3506788d595c6ce2adYorke Lee                RawContacts.PINNED,
334dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.AGGREGATION_MODE,
335dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
336dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
337dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
338dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
339dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
340dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
341dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
342dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDataProjection() {
343dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Data.CONTENT_URI, new String[]{
344dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
345dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RAW_CONTACT_ID,
346dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
347dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
348dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
349dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
350dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
351dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
352dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
353dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
354dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
355dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
356dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
357dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
358dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
359dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
360dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
361dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
362dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
363dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
364dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
365dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
366dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
367dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
368dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
369dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
370dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
371dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
372dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
373dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
374dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
375dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
376dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
377dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
378216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
379216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
380dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
381dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
38243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
38343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
384dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
385dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
386dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
387dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
38824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
389dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
390dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
391dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
392dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
393dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
394dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
395dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
396dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
397a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
398a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
399a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
400a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
401dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
402dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
403dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
40481fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
4059273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
406dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
407dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
408f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4093d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4103d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
411dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
412dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
413dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
414dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
415cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
416dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
417dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
418dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
419dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
420dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
421dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
422dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
4238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
424dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
425dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
426dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
427dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
428dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDistinctDataProjection() {
429dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Phone.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
430dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
431dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data._ID,
432dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
433dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
434dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
435dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
436dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
437dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
438dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
439dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
440dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
441dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
442dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
443dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
444dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
445dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
446dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
447dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
448dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
449dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
450dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
451dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
452dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
453dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
454dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
455dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
456dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CONTACT_ID,
457dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.PRESENCE,
458dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.CHAT_CAPABILITY,
459dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS,
460dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_TIMESTAMP,
461dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_RES_PACKAGE,
462dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_LABEL,
463dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.STATUS_ICON,
464216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.TIMES_USED,
465216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                Data.LAST_TIME_USED,
46624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
467dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts._ID,
468dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
469dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
470dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
471dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME,
472dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
473dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
474dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
475a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
476a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
477a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
478a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
479dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
480dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.TIMES_CONTACTED,
481dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.STARRED,
48281fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
4839273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
484dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
485dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.PHOTO_ID,
486f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
4873d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
4883d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
489cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
490dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
491dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
492dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.LOOKUP_KEY,
493dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_PRESENCE,
494dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
495dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS,
496dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
497dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
498dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
499dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
5008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
501dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
502dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
503dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
504dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
505a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testEntityProjection() {
506a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertProjection(
507a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI, 0),
508a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                    Contacts.Entity.CONTENT_DIRECTORY),
509a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            new String[]{
510a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity._ID,
511a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.DATA_ID,
512a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID,
513a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA_VERSION,
514a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_PRIMARY,
515a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.IS_SUPER_PRIMARY,
516a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.RES_PACKAGE,
517a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.MIMETYPE,
518a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA1,
519a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA2,
520a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA3,
521a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA4,
522a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA5,
523a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA6,
524a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA7,
525a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA8,
526a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA9,
527a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA10,
528a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA11,
529a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA12,
530a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA13,
531a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA14,
532a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.DATA15,
533a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC1,
534a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC2,
535a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC3,
536a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.SYNC4,
537a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CONTACT_ID,
538a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.PRESENCE,
539a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.CHAT_CAPABILITY,
540a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS,
541a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_TIMESTAMP,
542a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_RES_PACKAGE,
543a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_LABEL,
544a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Data.STATUS_ICON,
545a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_NAME,
546a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
54743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
54843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
549a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SOURCE_ID,
550a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.VERSION,
551a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DELETED,
552a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.DIRTY,
553a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.NAME_VERIFIED,
554a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC1,
555a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC2,
556a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC3,
557a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                RawContacts.SYNC4,
558a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts._ID,
559a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_PRIMARY,
560a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_ALTERNATIVE,
561a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.DISPLAY_NAME_SOURCE,
562a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME,
563a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHONETIC_NAME_STYLE,
564a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_PRIMARY,
565a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SORT_KEY_ALTERNATIVE,
566a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_PRIMARY,
567a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_PRIMARY,
568a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE,
569a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE,
570a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LAST_TIME_CONTACTED,
571a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.TIMES_CONTACTED,
572a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.STARRED,
57381fea08280784b319b936a3506788d595c6ce2adYorke Lee                Contacts.PINNED,
5749273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                Contacts.IN_DEFAULT_DIRECTORY,
575a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.IN_VISIBLE_GROUP,
576a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.PHOTO_ID,
577f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID,
5783d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_URI,
5793d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                Contacts.PHOTO_THUMBNAIL_URI,
580a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CUSTOM_RINGTONE,
581a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.SEND_TO_VOICEMAIL,
58224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Contacts.IS_USER_PROFILE,
583a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.LOOKUP_KEY,
584a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.NAME_RAW_CONTACT_ID,
585cf832869bcf91b8037d8b7f510a3a213b30764a3Dmitri Plotnikov                Contacts.HAS_PHONE_NUMBER,
586a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_PRESENCE,
587a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_CHAT_CAPABILITY,
588a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS,
589a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_TIMESTAMP,
590a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_RES_PACKAGE,
591a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_LABEL,
592a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.CONTACT_STATUS_ICON,
5938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
594a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
5959214ced257fea11a48d9ed0e2bbfd0da39cb4606Paul Soulos                DataUsageStatColumns.TIMES_USED,
5969214ced257fea11a48d9ed0e2bbfd0da39cb4606Paul Soulos                DataUsageStatColumns.LAST_TIME_USED,
597a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        });
598a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
599a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
600dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testRawEntityProjection() {
601dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(RawContactsEntity.CONTENT_URI, new String[]{
602dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.Entity.DATA_ID,
603dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts._ID,
604dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.CONTACT_ID,
605dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_NAME,
606dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.ACCOUNT_TYPE,
60743368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.DATA_SET,
60843368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
609dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SOURCE_ID,
610dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.VERSION,
611dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DIRTY,
612dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.NAME_VERIFIED,
613dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.DELETED,
614dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC1,
615dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC2,
616dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC3,
617dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.SYNC4,
618dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                RawContacts.STARRED,
61924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                RawContacts.RAW_CONTACT_IS_USER_PROFILE,
620dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA_VERSION,
621dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_PRIMARY,
622dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.IS_SUPER_PRIMARY,
623dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.RES_PACKAGE,
624dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.MIMETYPE,
625dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA1,
626dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA2,
627dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA3,
628dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA4,
629dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA5,
630dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA6,
631dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA7,
632dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA8,
633dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA9,
634dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA10,
635dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA11,
636dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA12,
637dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA13,
638dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA14,
639dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.DATA15,
640dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC1,
641dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC2,
642dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC3,
643dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Data.SYNC4,
644dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                GroupMembership.GROUP_SOURCE_ID,
645dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
646dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
647dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
648dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testPhoneLookupProjection() {
649dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(PhoneLookup.CONTENT_FILTER_URI.buildUpon().appendPath("123").build(),
650dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov            new String[]{
651dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup._ID,
652dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LOOKUP_KEY,
653dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.DISPLAY_NAME,
654dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LAST_TIME_CONTACTED,
655dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TIMES_CONTACTED,
656dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.STARRED,
6579273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                PhoneLookup.IN_DEFAULT_DIRECTORY,
658dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.IN_VISIBLE_GROUP,
6599701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.PHOTO_FILE_ID,
660dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.PHOTO_ID,
6613d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_URI,
6623d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                PhoneLookup.PHOTO_THUMBNAIL_URI,
663dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.CUSTOM_RINGTONE,
664dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.HAS_PHONE_NUMBER,
665dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.SEND_TO_VOICEMAIL,
666dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.NUMBER,
667dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.TYPE,
668dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PhoneLookup.LABEL,
6692530512f639c4979fd7371c7dd25dd67e8118124Bai Tao                PhoneLookup.NORMALIZED_NUMBER,
670dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
671dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
672dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
6739701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    public void testPhoneLookupEnterpriseProjection() {
6749701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertProjection(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI
6759701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        .buildUpon().appendPath("123").build(),
6769701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                new String[]{
6779701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup._ID,
6789701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.LOOKUP_KEY,
6799701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.DISPLAY_NAME,
6809701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.LAST_TIME_CONTACTED,
6819701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.TIMES_CONTACTED,
6829701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.STARRED,
6839701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.IN_DEFAULT_DIRECTORY,
6849701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.IN_VISIBLE_GROUP,
6859701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.PHOTO_FILE_ID,
6869701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.PHOTO_ID,
6879701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.PHOTO_URI,
6889701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.PHOTO_THUMBNAIL_URI,
6899701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.CUSTOM_RINGTONE,
6909701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.HAS_PHONE_NUMBER,
6919701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.SEND_TO_VOICEMAIL,
6929701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.NUMBER,
6939701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.TYPE,
6949701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.LABEL,
6959701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                        PhoneLookup.NORMALIZED_NUMBER,
6969701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                });
6979701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    }
6989701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
699dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsProjection() {
700dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_URI, new String[]{
701dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
702dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
703dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
70443368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
70543368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
706dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
707dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
708dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
709dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
710dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
711dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
712dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
713dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
714dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
715dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
716dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
717dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
718dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
719c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
720dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
721dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
722dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
723dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
724dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
725dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
726dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
727dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testGroupsSummaryProjection() {
728dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Groups.CONTENT_SUMMARY_URI, new String[]{
729dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups._ID,
730dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_NAME,
731dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.ACCOUNT_TYPE,
73243368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.DATA_SET,
73343368a3f9e05a979e454e278d6a0e8475f08923dDave Santoro                Groups.ACCOUNT_TYPE_AND_DATA_SET,
734dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SOURCE_ID,
735dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DIRTY,
736dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.VERSION,
737dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.RES_PACKAGE,
738dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE,
739dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.TITLE_RES,
740dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.GROUP_VISIBLE,
741dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYSTEM_ID,
742dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.DELETED,
743dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.NOTES,
744dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SHOULD_SYNC,
745dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.FAVORITES,
746dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.AUTO_ADD,
747c039cfb78c40730483fd71178df63ada5826a315Dmitri Plotnikov                Groups.GROUP_IS_READ_ONLY,
748dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC1,
749dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC2,
750dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC3,
751dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SYNC4,
752dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_COUNT,
753dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Groups.SUMMARY_WITH_PHONES,
75418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
755dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
756dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
757dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
758dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testAggregateExceptionProjection() {
759dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(AggregationExceptions.CONTENT_URI, new String[]{
760dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptionColumns._ID,
761dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.TYPE,
762dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID1,
763dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                AggregationExceptions.RAW_CONTACT_ID2,
764dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
765dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
766dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
767dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testSettingsProjection() {
768dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Settings.CONTENT_URI, new String[]{
769dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_NAME,
770dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ACCOUNT_TYPE,
771f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                Settings.DATA_SET,
772dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_VISIBLE,
773dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.SHOULD_SYNC,
774dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.ANY_UNSYNCED,
775dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_COUNT,
776dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Settings.UNGROUPED_WITH_PHONES,
777dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
778dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
779dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
780dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testStatusUpdatesProjection() {
781dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(StatusUpdates.CONTENT_URI, new String[]{
782dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID,
783dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.DATA_ID,
784dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_ACCOUNT,
785dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.IM_HANDLE,
786dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PROTOCOL,
787dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CUSTOM_PROTOCOL,
788dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.PRESENCE,
789dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.CHAT_CAPABILITY,
790dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS,
791dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_TIMESTAMP,
792dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_RES_PACKAGE,
793dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_ICON,
794dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                StatusUpdates.STATUS_LABEL,
795dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
796dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
797dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
798dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    public void testDirectoryProjection() {
799dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        assertProjection(Directory.CONTENT_URI, new String[]{
800dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory._ID,
801dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.PACKAGE_NAME,
802dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.TYPE_RESOURCE_ID,
803dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DISPLAY_NAME,
804dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.DIRECTORY_AUTHORITY,
805dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_TYPE,
806dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.ACCOUNT_NAME,
807dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov                Directory.EXPORT_SUPPORT,
808778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.SHORTCUT_SUPPORT,
809778d92d4dce5f76c649e2aca9d00d3f214cd7643Dmitri Plotnikov                Directory.PHOTO_SUPPORT,
810dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov        });
811dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov    }
812dd300fe5f5a1071b1c135af7c76e3ae149edda4dDmitri Plotnikov
8133cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testRawContactsInsert() {
8143cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
8153cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
8163cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_NAME, "a");
8173cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.ACCOUNT_TYPE, "b");
8189d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(RawContacts.DATA_SET, "ds");
8193cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SOURCE_ID, "c");
8203cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.VERSION, 42);
8213cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DIRTY, 1);
8223cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.DELETED, 1);
8233cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.AGGREGATION_MODE, RawContacts.AGGREGATION_MODE_DISABLED);
8243cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
8253cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
8263cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
8273cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
8283cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC1, "e");
8293cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC2, "f");
8303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC3, "g");
8313cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(RawContacts.SYNC4, "h");
8323cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
8333cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(RawContacts.CONTENT_URI, values);
8344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rowUri);
8353cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
8363cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
8374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(RawContacts.CONTENT_URI, values, RawContacts._ID, rawContactId);
83881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
8393cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
8403cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
8412149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    public void testDataDirectoryWithLookupUri() {
8422149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        ContentValues values = new ContentValues();
8432149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
8452149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertPhoneNumber(rawContactId, "555-GOOG-411");
8462149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        insertEmail(rawContactId, "google@android.com");
8472149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8482149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
8492149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
8502149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8512149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete and valid lookup URI
8522149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
8532149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Uri dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8542149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8552149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8562149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8572149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Complete but stale lookup URI
8582149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        lookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
8592149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(lookupUri, Contacts.Data.CONTENT_DIRECTORY);
8602149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8612149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8622149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        // Incomplete lookup URI (lookup key only, no contact ID)
8632149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        dataUri = Uri.withAppendedPath(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
8642149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov                lookupKey), Contacts.Data.CONTENT_DIRECTORY);
8652149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertDataRows(dataUri, values);
8662149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8672149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8682149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    private void assertDataRows(Uri dataUri, ContentValues values) {
8692149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        Cursor cursor = mResolver.query(dataUri, new String[]{ Data.DATA1 }, null, null, Data._ID);
8702149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertEquals(3, cursor.getCount());
8712149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToFirst();
8722149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "John Doe");
8732149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8742149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8752149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8762149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "555-GOOG-411");
8772149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8782149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8792149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.moveToNext();
8802149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        values.put(Data.DATA1, "google@android.com");
8812149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        assertCursorValues(cursor, values);
8822149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
8832149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov        cursor.close();
8842149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov    }
8852149ab82f021c204618d0d3644e261fd7a8d8490Dmitri Plotnikov
886a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithIdBasedUri() {
887a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
888a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
889a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
890a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
892a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
893a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
8945d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
895a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
8968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
897a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
898a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
899a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
900a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
901a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
902a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
903a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactUri, Contacts.Entity.CONTENT_DIRECTORY);
904a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
905a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
906a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
907a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
908a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContactEntitiesWithLookupUri() {
909a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
910a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account1 = new Account("act1", "actype1");
911a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Account account2 = new Account("act2", "actype2");
912a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
9138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, account1);
914a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertImHandle(rawContactId1, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
915a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", StatusUpdates.IDLE, "Busy", 90,
9165d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
917a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
9188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
919a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        setAggregationException(
920a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
921a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
922a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
923a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        String lookupKey = queryLookupKey(contactId);
924a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
925a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First try with a matching contact ID
926a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
927a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Uri entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
928a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
929a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
930a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try with a contact ID mismatch
931a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = ContactsContract.Contacts.getLookupUri(contactId + 1, lookupKey);
932a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
933a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
934a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
935a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Now try without an ID altogether
936a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        contactLookupUri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey);
937a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        entityUri = Uri.withAppendedPath(contactLookupUri, Contacts.Entity.CONTENT_DIRECTORY);
938a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEntityRows(entityUri, contactId, rawContactId1, rawContactId2);
939a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
940a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
941a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    private void assertEntityRows(Uri entityUri, long contactId, long rawContactId1,
942a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov            long rawContactId2) {
943a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        ContentValues values = new ContentValues();
944a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
945a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        Cursor cursor = mResolver.query(entityUri, null, null, null,
946a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov                Contacts.Entity.RAW_CONTACT_ID + "," + Contacts.Entity.DATA_ID);
947a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertEquals(3, cursor.getCount());
948a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
949a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // First row - name
950a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToFirst();
951a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
952a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
953a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
954a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "John Doe");
955a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
956a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
957a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
958a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
959a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
960a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
961a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
962a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
963a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
964a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
965a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
966a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Second row - IM
967a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
968a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
969a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId1);
970a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.MIMETYPE, Im.CONTENT_ITEM_TYPE);
971a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DATA1, "gtalk");
972a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act1");
973a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype1");
974a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
975a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
976a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
977a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
978a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
979a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
980a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.PRESENCE, StatusUpdates.IDLE);
981a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
982a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
983a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        // Third row - second raw contact, not data
984a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.moveToNext();
985a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_ID, contactId);
986a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.RAW_CONTACT_ID, rawContactId2);
987a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.MIMETYPE);
988a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA_ID);
989a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.DATA1);
990a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_NAME, "act2");
991a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.ACCOUNT_TYPE, "actype2");
992a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME, "John Doe");
993a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.DISPLAY_NAME_ALTERNATIVE, "Doe, John");
994a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.NAME_RAW_CONTACT_ID, rawContactId1);
995a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
996a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_PRESENCE, StatusUpdates.IDLE);
997a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(Contacts.Entity.CONTACT_STATUS, "Busy");
998a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.putNull(Contacts.Entity.PRESENCE);
999a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        assertCursorValues(cursor, values);
1000a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
1001a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        cursor.close();
1002a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    }
1003a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov
10043cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testDataInsert() {
10058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
10064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
10084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        putDataValues(values, rawContactId);
10094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
10104a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long dataId = ContentUris.parseId(dataUri);
10114a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10124a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10134a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(dataUri, values);
10154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Data.CONTENT_URI, values, Data._ID, dataId);
10174a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under RawContacts
10194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
10204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactDataUri =
10214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                Uri.withAppendedPath(rawContactUri, RawContacts.Data.CONTENT_DIRECTORY);
10224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(rawContactDataUri, values, Data._ID, dataId);
10234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        // Access the same data through the directory under Contacts
10254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
10264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactDataUri = Uri.withAppendedPath(contactUri, Contacts.Data.CONTENT_DIRECTORY);
10274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(contactDataUri, values, Data._ID, dataId);
102881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
10294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
10303cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
103189c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee    public void testDataInsertPhoneNumberTooLongIsTrimmed() {
103289c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
103389c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee
103489c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        ContentValues values = new ContentValues();
103589c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        values.put(Data.RAW_CONTACT_ID, rawContactId);
103689c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
103789c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        final StringBuilder sb = new StringBuilder();
103889c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        for (int i = 0; i < 300; i++) {
103989c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee            sb.append("12345");
104089c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        }
104189c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        final String phoneNumber1500Chars = sb.toString();
104289c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        values.put(Phone.NUMBER, phoneNumber1500Chars);
104389c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee
104489c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
104589c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        final long dataId = ContentUris.parseId(dataUri);
104689c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee
104789c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        sb.setLength(0);
104889c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        for (int i = 0; i < 200; i++) {
104989c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee            sb.append("12345");
105089c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        }
105189c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        final String phoneNumber1000Chars = sb.toString();
105289c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        final ContentValues expected = new ContentValues();
105389c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        expected.put(Phone.NUMBER, phoneNumber1000Chars);
105489c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee        assertSelection(dataUri, expected, Data._ID, dataId);
105589c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee    }
105689c3c5706ca0b4b061b3f3a1a7ee27d9c0e43d60Yorke Lee
105789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactDataQuery() {
105889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
105989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
10608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
10618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri1 = DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
10628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
10638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri2 = DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doe");
106489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
10658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(dataUri1, account1);
10668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(dataUri2, account2);
106789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Data._ID, ContentUris.parseId(dataUri1)) ;
106889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Data._ID, ContentUris.parseId(dataUri2)) ;
106989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
107089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
10714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesQuery() {
10727d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
10733cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
10744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
10754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
10764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
10774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
10784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
10794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
10814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
10824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
10844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri uri = insertPhoneNumber(rawContactId, "18004664411");
10854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long phoneId = ContentUris.parseId(uri);
10864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
10884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
10894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
10904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, phoneId);
10913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
10924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
10934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
10944a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
10954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
10964a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
10974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
10984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
10994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
11004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
11014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
11024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
11034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
110448828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Phone.CONTENT_URI, phoneId), values);
11054a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Phone.CONTENT_URI, values, Data._ID, phoneId);
11064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
11074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1108cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    public void testPhonesWithMergedContacts() {
11098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
1110cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "123456789", true);
1111cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
11128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
1113cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "123456789", true);
1114cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
11150992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
11160992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki                rawContactId1, rawContactId2);
11170992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        assertNotAggregated(rawContactId1, rawContactId2);
11180992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki
1119cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        ContentValues values1 = new ContentValues();
1120cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "123456789");
1121cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1122cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        values1.put(Phone.NUMBER, "123456789");
1123cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
11240992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // There are two phone numbers, so we should get two rows.
1125cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
1126cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
11270992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now set the dedupe flag.  But still we should get two rows, because they're two
11280992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // different contacts.  We only dedupe within each contact.
11298ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Phone.CONTENT_URI.buildUpon()
11308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
11318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
11328ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, new ContentValues[] {values1, values1});
11338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
11340992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now join them into a single contact.
1135cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
1136cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa                rawContactId1, rawContactId2);
1137cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1138cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa        assertAggregated(rawContactId1, rawContactId2, "123456789");
1139cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
11400992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Contact merge won't affect the default result of Phone Uri, where we don't dedupe.
11418ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Phone.CONTENT_URI, new ContentValues[] {values1, values1});
11428ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
11430992b9d4969ed0eee6e879db94292b635229e2b7Makoto Onuki        // Now we dedupe them.
11448ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values1);
1145cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa    }
1146cf55cbe8932f620484a3634d13ecc116c32fdc99Daisuke Miyakawa
1147904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    public void testPhonesNormalizedNumber() {
11488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver);
1149904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1150904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Write both a number and a normalized number. Those should be written as-is
1151904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final ContentValues values = new ContentValues();
1152904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.RAW_CONTACT_ID, rawContactId);
1153904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
1154904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "1234");
1155904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "5678");
1156904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.TYPE, Phone.TYPE_HOME);
1157904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
1158904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        final Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
1159904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
116010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the lookup table.
1161904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1162904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1163904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1164904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1165904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
116610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Check the data table.
116710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
116810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1234", Phone.NORMALIZED_NUMBER, "5678")
116910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
117010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1171904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace both in an UPDATE
1172904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1173904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NUMBER, "4321");
1174904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1175904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1176904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1177904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "1234"), null, null));
1178904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1179904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "4321"), null, null));
1180904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1181904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "5678"), null, null));
1182904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(1,
1183904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1184904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
118510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
118610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "4321", Phone.NORMALIZED_NUMBER, "8765")
118710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
118810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1189904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NUMBER ==> NORMALIZED_NUMBER will be inferred (we test that by making
1190904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // sure the old manual value can not be found anymore)
1191904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
119210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "+1-800-466-5432");
1193904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1194904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1195904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
119610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1197904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1198904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1199904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
1200904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
120110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
120210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
120310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
120410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
1205904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        // Replace only NORMALIZED_NUMBER ==> call is ignored, things will be unchanged
1206904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.clear();
1207904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        values.put(Phone.NORMALIZED_NUMBER, "8765");
1208904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        mResolver.update(dataUri, values, null, null);
1209904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(
1210904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                1,
121110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "+1-800-466-5432"), null,
1212904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                        null));
1213904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann        assertEquals(0,
1214904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "8765"), null, null));
121510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
121610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
121710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "+1-800-466-5432", Phone.NORMALIZED_NUMBER, "+18004665432")
121810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
121910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
122010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // Replace NUMBER with an "invalid" number which can't be normalized.  It should clear
122110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // NORMALIZED_NUMBER.
122210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
122310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 1. Set 999 to NORMALIZED_NUMBER explicitly.
122410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
122510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "888");
122610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NORMALIZED_NUMBER, "999");
122710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
122810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
122910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(1,
123010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
123110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
123210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
123310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "888", Phone.NORMALIZED_NUMBER, "999")
123410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
123510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
123610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        // 2. Set an invalid number to NUMBER.
123710840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.clear();
123810840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        values.put(Phone.NUMBER, "1");
123910840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        mResolver.update(dataUri, values, null, null);
124010840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
124110840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertEquals(0,
124210840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                getCount(Uri.withAppendedPath(Phone.CONTENT_FILTER_URI, "999"), null, null));
124310840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki
124410840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki        assertStoredValues(dataUri,
124510840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                cv(Phone.NUMBER, "1", Phone.NORMALIZED_NUMBER, null)
124610840c6bcd8bf0ab2e5f846d345d14e5df9858a7Makoto Onuki                );
1247904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann    }
1248904f4a2addf4fdf063cb40185cb73252ff0edefdDaniel Lehmann
12494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPhonesFilterQuery() {
1250e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Phone.CONTENT_FILTER_URI);
1251e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
1252e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1253e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /**
1254e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * A convenient method for {@link #testPhonesFilterQuery()} and
1255e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link #testCallablesFilterQuery()}.
1256e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1257e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * This confirms if both URIs return identical results for phone-only contacts and
1258e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * appropriately different results for contacts with sip addresses.
1259e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     *
1260e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * @param baseFilterUri Either {@link Phone#CONTENT_FILTER_URI} or
1261e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     * {@link Callable#CONTENT_FILTER_URI}.
1262e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa     */
1263e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    private void testPhonesFilterQueryInter(Uri baseFilterUri) {
1264e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertTrue("Unsupported Uri (" + baseFilterUri + ")",
1265e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                Phone.CONTENT_FILTER_URI.equals(baseFilterUri)
1266e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                        || Callable.CONTENT_FILTER_URI.equals(baseFilterUri));
1267e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
12688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot",
12698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale", TestUtil.ACCOUNT_1);
12705e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertPhoneNumber(rawContactId1, "1-800-466-4411");
12715e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
12728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Chilled",
12738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Guacamole", TestUtil.ACCOUNT_2);
12742a8fefb86282c06a7669f80e1b2b86d87619dfc2Dmitri Plotnikov        insertPhoneNumber(rawContactId2, "1-800-466-5432");
127558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "0@example.com", false, Phone.TYPE_PAGER);
127658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "1@example.com", false, Phone.TYPE_PAGER);
12775e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1278e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri1 = Uri.withAppendedPath(baseFilterUri, "tamale");
12794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
12804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
12814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
12825e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Phone.NUMBER, "1-800-466-4411");
12834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Phone.TYPE, Phone.TYPE_HOME);
12844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Phone.LABEL);
12855e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
12864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1287e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri2 = Uri.withAppendedPath(baseFilterUri, "1-800-GOOG-411");
12885e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri2, values);
12895e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1290e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri3 = Uri.withAppendedPath(baseFilterUri, "18004664");
12915e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValues(filterUri3, values);
12925e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
1293e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri4 = Uri.withAppendedPath(baseFilterUri, "encilada");
12945e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri4, null, null));
129545d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov
1296e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri5 = Uri.withAppendedPath(baseFilterUri, "*");
129745d8626bf586b5c7111fa86324a7201ae8073607Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
129858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
129958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values1 = new ContentValues();
130058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
130158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
130258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.NUMBER, "1-800-466-5432");
130358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
130458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values1.putNull(Phone.LABEL);
130558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
130658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values2 = new ContentValues();
130758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
130858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
130958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.NUMBER, "0@example.com");
131058567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.put(Phone.TYPE, Phone.TYPE_PAGER);
131158567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values2.putNull(Phone.LABEL);
131258567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
131358567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        ContentValues values3 = new ContentValues();
131458567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Contacts.DISPLAY_NAME, "Chilled Guacamole");
131558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
131658567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.NUMBER, "1@example.com");
131758567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.put(Phone.TYPE, Phone.TYPE_PAGER);
131858567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        values3.putNull(Phone.LABEL);
131958567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa
1320e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri6 = Uri.withAppendedPath(baseFilterUri, "Chilled");
1321dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValues(filterUri6, new ContentValues[]{values1, values2, values3});
1322e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1323e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Insert a SIP address. From here, Phone URI and Callable URI may return different results
1324e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // than each other.
1325e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip_hot_tamale@example.com");
1326e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        insertSipAddress(rawContactId1, "sip:sip_hot@example.com");
1327e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1328e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri7 = Uri.withAppendedPath(baseFilterUri, "sip_hot");
1329e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        final Uri filterUri8 = Uri.withAppendedPath(baseFilterUri, "sip_hot_tamale");
1330e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        if (Callable.CONTENT_FILTER_URI.equals(baseFilterUri)) {
1331e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values4 = new ContentValues();
1332e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1333e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1334e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values4.put(SipAddress.SIP_ADDRESS, "sip_hot_tamale@example.com");
1335e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1336e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            ContentValues values5 = new ContentValues();
1337e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Contacts.DISPLAY_NAME, "Hot Tamale");
1338e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
1339e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            values5.put(SipAddress.SIP_ADDRESS, "sip:sip_hot@example.com");
1340e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri1, new ContentValues[] {values, values4, values5});
1341e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1342e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri7, new ContentValues[] {values4, values5});
1343e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValues(filterUri8, values4);
1344e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        } else {
1345e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            // Sip address should not affect Phone URI.
1346e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertStoredValuesWithProjection(filterUri1, values);
1347e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa            assertEquals(0, getCount(filterUri7, null, null));
1348e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        }
1349e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
1350e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // Sanity test. Run tests for "Chilled Guacamole" again and see nothing changes
1351e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        // after the Sip address being inserted.
1352e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(filterUri2, values);
1353e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri4, null, null));
1354e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(0, getCount(filterUri5, null, null));
135558567abca253f1efa2db5c39e17e42dca589e916Daisuke Miyakawa        assertStoredValues(filterUri6, new ContentValues[] {values1, values2, values3} );
13564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
13574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
13584c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    public void testPhonesFilterSearchParams() {
13598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "Dad", null);
13604c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid1, "123-456-7890");
13614c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
13628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "Mam", null);
13634c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        insertPhoneNumber(rid2, "323-123-4567");
13644c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
13654c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // By default, "dad" will match both the display name and the phone number.
13664c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        // Because "dad" is "323" after the dialpad conversion, it'll match "Mam" too.
13674c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13684c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad").build(),
13694c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890"),
13704c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
13714c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13724c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13734c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13744c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
13754c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13764c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Dad", Phone.NUMBER, "123-456-7890")
13774c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13784c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
13794c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13804c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
13814c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
13824c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                    .build(),
13834c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                cv(Phone.DISPLAY_NAME, "Mam", Phone.NUMBER, "323-123-4567")
13844c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                );
13854c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki        assertStoredValues(
13864c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki                Phone.CONTENT_FILTER_URI.buildUpon().appendPath("dad")
1387dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_DISPLAY_NAME_KEY, "0")
1388dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .appendQueryParameter(Phone.SEARCH_PHONE_NUMBER_KEY, "0")
1389dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                        .build()
1390dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        );
13914c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki    }
13924c3a04572ead6ad9f0cfc20a34db3252fdb31201Makoto Onuki
1393e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov    public void testPhoneLookup() {
1394e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        ContentValues values = new ContentValues();
1395e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1396e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1397e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1398e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1399e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
1400e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
14018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
14024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
14034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1404ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // We'll create two lookup records, 18004664411 and +18004664411, and the below lookup
1405ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        // will match both.
1406ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki
14074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
1408e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov
1409e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.clear();
1410e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup._ID, queryContactId(rawContactId));
1411e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.DISPLAY_NAME, "Hot Tamale");
1412e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.NUMBER, "18004664411");
1413e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.TYPE, Phone.TYPE_HOME);
1414e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.putNull(PhoneLookup.LABEL);
1415e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.CUSTOM_RINGTONE, "d");
1416e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        values.put(PhoneLookup.SEND_TO_VOICEMAIL, 1);
1417ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[] {values, values});
14184a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
1419892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // In the context that 8004664411 is a valid number, "4664411" as a
142034984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        // call id should  match to both "8004664411" and "+18004664411".
1421e3eb7ef438010c893c429f3031dcc7298171865dDmitri Plotnikov        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "4664411");
142234984173c94fffb45710673f4f92150b87134ce4Shaopeng Jia        assertEquals(2, getCount(lookupUri2, null, null));
14236db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
14246db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // A wrong area code 799 vs 800 should not be matched
14256db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "7994664411");
14266db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
1427892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    }
1428892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1429bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupStarUseCases() {
1430bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Create two raw contacts with numbers "*123" and "12 3". This is a real life example
1431bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // from b/13195334.
1432bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1433bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1434bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        long rawContactId = ContentUris.parseId(rawContactUri);
1435bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId, "Emergency", /* familyName =*/ null);
1436bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId, "*123");
1437bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1438bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1439bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        rawContactId = ContentUris.parseId(rawContactUri);
1440bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId, "Voicemail", /* familyName =*/ null);
1441bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId, "12 3");
1442bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1443bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Verify: "123" returns the "Voicemail" raw contact id. It should not match
1444bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // a phone number that starts with a "*".
1445bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "123");
1446bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.clear();
1447bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.put(PhoneLookup.DISPLAY_NAME, "Voicemail");
1448bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertStoredValues(lookupUri, null, null, new ContentValues[] {values});
1449bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1450bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "(1) 23");
1451bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.clear();
1452bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.put(PhoneLookup.DISPLAY_NAME, "Voicemail");
1453bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertStoredValues(lookupUri, null, null, new ContentValues[] {values});
1454bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1455bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Verify: "*123" returns the "Emergency" raw contact id.
1456bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "*1-23");
1457bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.clear();
1458bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.put(PhoneLookup.DISPLAY_NAME, "Emergency");
1459bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertStoredValues(lookupUri, null, null, new ContentValues[] {values});
1460bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1461bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1462bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupReturnsNothingRatherThanStar() {
1463bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Create Emergency raw contact with "*123456789" number.
1464bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1465bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1466bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final long rawContactId1 = ContentUris.parseId(rawContactUri);
1467bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId1, "Emergency",
1468bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1469bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId1, "*123456789");
1470bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1471bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Lookup should return no results. It does not ignore stars even when no other matches.
1472bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "123456789");
1473bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertEquals(0, getCount(lookupUri, null, null));
1474bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1475bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1476bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupReturnsNothingRatherThanMissStar() {
1477bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Create Voice Mail raw contact with "123456789" number.
1478bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1479bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1480bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final long rawContactId1 = ContentUris.parseId(rawContactUri);
1481bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId1, "Voice mail",
1482bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1483bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId1, "123456789");
1484bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1485bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Lookup should return no results. It does not ignore stars even when no other matches.
1486bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "*123456789");
1487bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertEquals(0, getCount(lookupUri, null, null));
1488bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1489bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1490bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupStarNoFallbackMatch() {
1491bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1492bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1493bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final long rawContactId1 = ContentUris.parseId(rawContactUri);
1494bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId1, "Voice mail",
1495bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1496bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId1, "*011123456789");
1497bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1498bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // The numbers "+123456789" and "*011123456789" are a "fallback" match. The + is equivalent
1499bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // to "011". This lookup should return no results. Lookup does not ignore
1500bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // stars, even when doing a fallback lookup.
1501bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+123456789");
1502bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        assertEquals(0, getCount(lookupUri, null, null));
1503bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1504bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1505bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupStarNotBreakFallbackMatching() {
1506bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Create a raw contact with a phone number starting with "011"
1507bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
1508bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        long rawContactId = ContentUris.parseId(rawContactUri);
1509bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId, "No star",
1510bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1511bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId, "011123456789");
1512bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1513bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Create a raw contact with a phone number starting with "*011"
1514bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
1515bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        rawContactId = ContentUris.parseId(rawContactUri);
1516bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId, "Has star",
1517bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1518bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId, "*011123456789");
1519bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1520bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // A phone number starting with "+" can (fallback) match the same phone number starting
1521bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // with "001". Verify that this fallback matching still occurs in the presence of
1522bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // numbers starting with "*"s.
1523bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
1524bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                "+123456789");
1525bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1526bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        values.put(PhoneLookup.DISPLAY_NAME, "No star");
15279701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertStoredValues(lookupUri1, null, null, new ContentValues[]{values});
1528bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1529bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1530bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    public void testPhoneLookupExplicitProjection() {
1531bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final ContentValues values = new ContentValues();
1532bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1533bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        final long rawContactId1 = ContentUris.parseId(rawContactUri);
1534bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        DataUtil.insertStructuredName(mResolver, rawContactId1, "Voice mail",
1535bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell                /* familyName =*/ null);
1536bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        insertPhoneNumber(rawContactId1, "+1234567");
1537bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1538bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Performing a query with a non-null projection with or without PhoneLookup.Number inside
1539bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // it should not cause a crash.
1540bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "1234567");
1541bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        String[] projection = new String[] {PhoneLookup.DISPLAY_NAME};
1542bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        mResolver.query(lookupUri, projection, null, null, null);
1543bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        projection = new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.NUMBER};
1544bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        mResolver.query(lookupUri, projection, null, null, null);
1545bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1546bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        // Shouldn't crash for a fallback query either
1547bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "*0111234567");
1548bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        projection = new String[] {PhoneLookup.DISPLAY_NAME};
1549bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        mResolver.query(lookupUri, projection, null, null, null);
1550bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        projection = new String[] {PhoneLookup.DISPLAY_NAME, PhoneLookup.NUMBER};
1551bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell        mResolver.query(lookupUri, projection, null, null, null);
1552bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell    }
1553bf98e55afd5f39f72dc05c704409655b89a7fa25Brian Attwell
1554892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov    public void testPhoneLookupUseCases() {
1555892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        ContentValues values = new ContentValues();
1556892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri rawContactUri;
1557892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        long rawContactId;
1558892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        Uri lookupUri2;
1559892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1560892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1561892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1562892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1563892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // International format in contacts
1564892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1565892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1566892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
15678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
1568892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "+1-650-861-0000");
1569892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1570892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1571892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1572892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1573892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0000");
1574892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1575892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1576892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1577892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0000");
1578892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1579892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
15806db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with wrong area code
15816db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "649 861 0000");
15826db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
15836db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
15846db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digits in mistyped area code
15856db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "5 861 0000");
15866db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
15876db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
15886db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // does not match with missing digit in mistyped area code
15896db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "65 861 0000");
15906db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(0, getCount(lookupUri2, null, null));
15916db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee
1592892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // National format in contacts
1593892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1594892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1595892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1596892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1597892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1598892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
15998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot1", "Tamale");
1600892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "650-861-0001");
1601892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1602892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1603892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1604892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1605892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0001");
1606892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1607892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1608892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1609892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0001");
1610892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(2, getCount(lookupUri2, null, null));
1611892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1612892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // Local format in contacts
1613892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1614892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
1615892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1616892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
1617892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        rawContactId = ContentUris.parseId(rawContactUri);
1618892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
16198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot2", "Tamale");
1620892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        insertPhoneNumber(rawContactId, "861-0002");
1621892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1622892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        values.clear();
1623892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1624892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with international format
1625892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "+1 650 861 0002");
1626892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
1627892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov
1628892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        // match with national format
1629892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "650 861 0002");
1630892a3d9ded5c64a63ae3d5d5c52c59528b466c93Dmitri Plotnikov        assertEquals(1, getCount(lookupUri2, null, null));
16314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
16324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
163356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testIntlPhoneLookupUseCases() {
16346db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Checks the logic that relies on phone_number_compare_loose(Gingerbread) as a fallback
16356db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        //for phone number lookups.
163656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String fullNumber = "01197297427289";
163756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
163856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
163956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
164056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
164156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
16428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
164356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, fullNumber);
164456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
164556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Full number should definitely match.
164656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
164756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
164856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
164956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Shorter (local) number with 0 prefix should also match.
165056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
165156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "097427289"), null, null));
165256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
16536db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        // Number with international (+972) prefix should also match.
16546db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee        assertEquals(1, getCount(Uri.withAppendedPath(
16556db6c6d74da066cbbe3e3b5b89caf1ba5626d240Yorke Lee                PhoneLookup.CONTENT_FILTER_URI, "+97297427289"), null, null));
165656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
165756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with dashes should match.
165856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
165956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09-742-7289"), null, null));
166056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
166156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Same shorter number with spaces should match.
166256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(2, getCount(Uri.withAppendedPath(
166356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "09 742 7289"), null, null));
166456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
166556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Some other number should not match.
166656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(0, getCount(Uri.withAppendedPath(
166756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "049102395"), null, null));
166856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
166956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
167056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    public void testPhoneLookupB5252190() {
167156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        // Test cases from b/5252190
167256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        String storedNumber = "796010101";
167356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
167456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        ContentValues values = new ContentValues();
167556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.CUSTOM_RINGTONE, "d");
167656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
167756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(RawContacts.CONTENT_URI, values));
16788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
167956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        insertPhoneNumber(rawContactId, storedNumber);
168056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
168156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
168256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "0796010101"), null, null));
168356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
168456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
168556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "+48796010101"), null, null));
168656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
168756abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
168856abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "48796010101"), null, null));
168956abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
169056abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
169156abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4-879-601-0101"), null, null));
169256abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
169356abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro        assertEquals(1, getCount(Uri.withAppendedPath(
169456abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro                PhoneLookup.CONTENT_FILTER_URI, "4 879 601 0101"), null, null));
169556abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro    }
169656abe81ced08c7af625b3eb8dd543f9030da9badDave Santoro
1697a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    public void testPhoneLookupUseStrictPhoneNumberCompare() {
1698a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Test lookup cases when mUseStrictPhoneNumberComparison is true
1699a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
1700a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
1701a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // Get and save the original value of mUseStrictPhoneNumberComparison so that we
1702a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        // can restore it when we are done with the test
1703a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        final boolean oldUseStrict = dbHelper.getUseStrictPhoneNumberComparisonForTest();
1704a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        dbHelper.setUseStrictPhoneNumberComparisonForTest(true);
1705a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1706a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1707a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        try {
1708a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            String fullNumber = "01197297427289";
1709a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            ContentValues values = new ContentValues();
1710a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.CUSTOM_RINGTONE, "d");
1711a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
1712a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            long rawContactId = ContentUris.parseId(
1713a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    mResolver.insert(RawContacts.CONTENT_URI, values));
17148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            DataUtil.insertStructuredName(mResolver, rawContactId, "Senor", "Chang");
1715a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, fullNumber);
1716a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "5103337596");
1717a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            insertPhoneNumber(rawContactId, "+19012345678");
1718a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for full number
1719a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1720a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, fullNumber), null, null));
1721a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1722a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra digit at the front
1723a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1724a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "55103337596"), null, null));
1725a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for mispelled area code
1726a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1727a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "5123337596"), null, null));
1728a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1729a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with dashes
1730a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1731a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "510-333-7596"), null, null));
1732a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1733a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // One match for matching number with international code
1734a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(1, getCount(Uri.withAppendedPath(
1735a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+1-510-333-7596"), null, null));
1736a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1737a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1738a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for extra 0 in front
1739a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1740a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "0-510-333-7596"), null, null));
1741a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1742a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
1743a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // No matches for different country code
1744a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            assertEquals(0, getCount(Uri.withAppendedPath(
1745a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee                    PhoneLookup.CONTENT_FILTER_URI, "+819012345678"), null, null));
1746a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            values.clear();
1747a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        } finally {
1748a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // restore the original value of mUseStrictPhoneNumberComparison
1749a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            // upon test completion or failure
1750a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee            dbHelper.setUseStrictPhoneNumberComparisonForTest(oldUseStrict);
1751a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee        }
1752a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee    }
1753a6f9ec007fb108f9f82e73bfdaef7ffc5e67cffcYorke Lee
17549701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    /**
17559701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     * Test for enterprise caller-id, but with no corp profile.
17569701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     */
17579701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    public void testPhoneLookupEnterprise_noCorpProfile() throws Exception {
17589701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17599701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Uri uri1 = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, "408-111-1111");
17609701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17619701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // No contacts profile, no data.
17629701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(0, getCount(uri1));
17639701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17649701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a contact into the primary CP2.
17659701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        long rawContactId = ContentUris.parseId(
17669701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                mResolver.insert(RawContacts.CONTENT_URI, new ContentValues()));
17679701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        DataUtil.insertStructuredName(mResolver, rawContactId, "Contact1", "Doe");
17689701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        insertPhoneNumber(rawContactId, "408-111-1111");
17699701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17709701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Do the query again and check the result.
17719701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Cursor c = mResolver.query(uri1, null, null, null, null);
17729701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        try {
17739701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            assertEquals(1, c.getCount());
17749701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.moveToPosition(0);
17759701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            long contactId = c.getLong(c.getColumnIndex(PhoneLookup._ID));
1776ec9680853b8526568a96805e38af77f3c6da175aMakoto Onuki            assertFalse(Contacts.isEnterpriseContactId(contactId)); // Make sure it's not rewritten.
17779701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        } finally {
17789701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.close();
17799701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        }
17809701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    }
17819701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17829701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    /**
17839701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     * Set up the corp user / CP2 and returns the corp CP2 instance.
178471142b333418ac7d589bd7522dad77b967f0bbe1Makoto Onuki     *
178571142b333418ac7d589bd7522dad77b967f0bbe1Makoto Onuki     * Create a second instance of CP2, and add it to the resolver, with the "user-id@" authority.
17869701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     */
17879701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    private SynchronousContactsProvider2 setUpCorpProvider() throws Exception {
17889701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        mActor.mockUserManager.setUsers(MockUserManager.PRIMARY_USER, MockUserManager.CORP_USER);
17899701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17909701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Note here we use a standalone CP2 so it'll have its own db helper.
17919701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Also use AlteringUserContext here to report the corp user id.
17929701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        return mActor.addProvider(StandaloneContactsProvider2.class,
17939701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "" + MockUserManager.CORP_USER.id + "@com.android.contacts",
17949701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                new AlteringUserContext(mActor.getProviderContext(), MockUserManager.CORP_USER.id));
17959701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    }
17969701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
17979701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    /**
17989701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     * Test for enterprise caller-id, with the corp profile.
17999701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     *
18009701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     * Note: in this test, we add one more provider instance for the authority
18019701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     * "10@com.android.contacts" and use it as the corp cp2.
18029701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki     */
18039701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    public void testPhoneLookupEnterprise_withCorpProfile() throws Exception {
18049701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        final SynchronousContactsProvider2 corpCp2 = setUpCorpProvider();
18059701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18069701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Uri uri1 = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, "408-111-1111");
18079701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Uri uri2 = Uri.withAppendedPath(PhoneLookup.ENTERPRISE_CONTENT_FILTER_URI, "408-222-2222");
18089701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18099701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // First, test with no contacts on either profile.
18109701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(0, getCount(uri1));
18119701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18129701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a contact to the primary CP2.
18139701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        long rawContactId = ContentUris.parseId(
18149701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                mResolver.insert(RawContacts.CONTENT_URI, new ContentValues()));
18159701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        DataUtil.insertStructuredName(mResolver, rawContactId, "Contact1", "Doe");
18169701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        insertPhoneNumber(rawContactId, "408-111-1111");
18179701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18189701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a contact to the corp CP2, with the same phone number, but with a different name.
18199701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        rawContactId = ContentUris.parseId(
18209701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                corpCp2.insert(RawContacts.CONTENT_URI, new ContentValues()));
18219701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a name
18229701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        ContentValues cv = cv(
18239701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.RAW_CONTACT_ID, rawContactId,
18249701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE,
18259701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.DISPLAY_NAME, "Contact2 Corp",
18269701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.GIVEN_NAME, "Contact2",
18279701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.FAMILY_NAME, "Corp");
18289701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        corpCp2.insert(ContactsContract.Data.CONTENT_URI, cv);
18299701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18309701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a number
18319701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        cv = cv(
18329701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.RAW_CONTACT_ID, rawContactId,
18339701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE,
18349701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Phone.NUMBER, "408-111-1111",
18359701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Phone.TYPE, Phone.TYPE_HOME);
18369701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        corpCp2.insert(ContactsContract.Data.CONTENT_URI, cv);
18379701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18389701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert one more contact to the corp CP2, with a different number.
18399701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        rawContactId = ContentUris.parseId(
18409701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                corpCp2.insert(RawContacts.CONTENT_URI, new ContentValues()));
18419701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a name
18429701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        cv = cv(
18439701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.RAW_CONTACT_ID, rawContactId,
18449701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE,
18459701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.DISPLAY_NAME, "Contact3 Corp",
18469701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.GIVEN_NAME, "Contact3",
18479701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                StructuredName.FAMILY_NAME, "Corp");
18489701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        corpCp2.insert(ContactsContract.Data.CONTENT_URI, cv);
18499701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18509701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Insert a number
18519701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        cv = cv(
18529701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.RAW_CONTACT_ID, rawContactId,
18539701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE,
18549701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Phone.NUMBER, "408-222-2222",
18559701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                Phone.TYPE, Phone.TYPE_HOME);
18569701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        corpCp2.insert(ContactsContract.Data.CONTENT_URI, cv);
18579701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18589701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Okay, now execute queries and check the result.
18599701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18609701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // The first URL hits the contact in the primary CP2.
18619701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // There's also a contact with this phone number in the corp CP2, but that will be ignored.
18629701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Cursor c = mResolver.query(uri1, null, null, null, null);
18639701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        try {
18649701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            assertEquals(1, c.getCount());
18659701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.moveToPosition(0);
18669701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            assertEquals("Contact1 Doe", c.getString(c.getColumnIndex(PhoneLookup.DISPLAY_NAME)));
18679701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18689701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            // Make sure it has a personal contact ID.
18699701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            long contactId = c.getLong(c.getColumnIndex(PhoneLookup._ID));
1870ec9680853b8526568a96805e38af77f3c6da175aMakoto Onuki            assertFalse(Contacts.isEnterpriseContactId(contactId));
18719701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        } finally {
18729701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.close();
18739701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        }
18749701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18759701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // Test for the second phone number, which only exists in the corp cp2.
18769701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        c = mResolver.query(uri2, null, null, null, null);
18779701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        try {
18789701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            // This one actually returns 2 identical rows, probably because of the join
18799701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            // in phone_lookup.  Callers only care the first row, so returning multiple identical
18809701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            // rows should be fine.
18819701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            assertTrue(c.getCount() > 0);
18829701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.moveToPosition(0);
18839701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            assertEquals("Contact3 Corp", c.getString(c.getColumnIndex(PhoneLookup.DISPLAY_NAME)));
18849701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
18859701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            // Make sure it has a corp contact ID.
18869701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            long contactId = c.getLong(c.getColumnIndex(PhoneLookup._ID));
1887ec9680853b8526568a96805e38af77f3c6da175aMakoto Onuki            assertTrue(Contacts.isEnterpriseContactId(contactId));
18889701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        } finally {
18899701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki            c.close();
18909701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        }
18919701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    }
18929701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
1893a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee    public void testUpgradeToVersion910_CallsDeletedForCorpProfileOnly() throws Exception {
1894a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        CallLogProvider provider =
1895a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee                (CallLogProvider) addProvider(TestCallLogProvider.class, CallLog.AUTHORITY);
1896a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        final ContactsDatabaseHelper helper = provider.getDatabaseHelper(mContext);
1897a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        final SQLiteDatabase db = helper.getWritableDatabase();
1898a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1899a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        final ContentValues values = new ContentValues();
1900a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        values.put(Calls.NUMBER, "123456789");
1901a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        values.put(Calls.DATE, System.currentTimeMillis());
1902a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        values.put(Calls.TYPE, Calls.OUTGOING_TYPE);
1903a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        values.put(Calls.DURATION, 10000);
1904a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1905a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        mResolver.insert(Calls.CONTENT_URI, values);
1906a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        assertEquals(1, getCount(Calls.CONTENT_URI));
1907a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1908a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        helper.upgradeToVersion910(db);
1909a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        assertEquals(1, getCount(Calls.CONTENT_URI));
1910a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1911a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        mActor.mockUserManager.myUser = MockUserManager.CORP_USER.id;
1912a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        mActor.mockUserManager.setUsers(MockUserManager.CORP_USER);
1913a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1914a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        helper.upgradeToVersion910(db);
1915a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
1916a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        // Switch back to the primary user to ensure that the calls table was really cleared, and
1917a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        // we are not getting an empty cursor just because of the call log read/write restriction
1918a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        // on managed profiles.
1919a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        mActor.mockUserManager.myUser = MockUserManager.PRIMARY_USER.id;
1920a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        mActor.mockUserManager.setUsers(MockUserManager.PRIMARY_USER);
1921a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee        assertEquals(0, getCount(Calls.CONTENT_URI));
1922a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee    }
1923a5d6539589c851152bbf6665c1addfc2c7292dbaYorke Lee
19249701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    public void testRewriteCorpPhoneLookup() {
19259701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // 19 columns
19269701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        final MatrixCursor c = new MatrixCursor(new String[] {
19279701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup._ID,
19289701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.LOOKUP_KEY,
19299701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.DISPLAY_NAME,
19309701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.LAST_TIME_CONTACTED,
19319701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.TIMES_CONTACTED,
19329701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.STARRED,
19339701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.IN_DEFAULT_DIRECTORY,
19349701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.IN_VISIBLE_GROUP,
19359701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.PHOTO_FILE_ID,
19369701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.PHOTO_ID,
19379701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.PHOTO_URI,
19389701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.PHOTO_THUMBNAIL_URI,
19399701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.CUSTOM_RINGTONE,
19409701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.HAS_PHONE_NUMBER,
19419701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.SEND_TO_VOICEMAIL,
19429701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.NUMBER,
19439701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.TYPE,
19449701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.LABEL,
19459701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                PhoneLookup.NORMALIZED_NUMBER
19469701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        });
19479701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
19489701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        // First, convert and make sure it returns an empty cursor.
19499701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        Cursor rewritten = ContactsProvider2.rewriteCorpPhoneLookup(c);
19509701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(0, rewritten.getCount());
19519701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(19, rewritten.getColumnCount());
19529701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
19539701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        c.addRow(new Object[] {
19549701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1L, // PhoneLookup._ID,
19559701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.LOOKUP_KEY,
19569701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.DISPLAY_NAME,
19579701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.LAST_TIME_CONTACTED,
19589701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.TIMES_CONTACTED,
19599701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.STARRED,
19609701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.IN_DEFAULT_DIRECTORY,
19619701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.IN_VISIBLE_GROUP,
19629701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.PHOTO_FILE_ID,
19639701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.PHOTO_ID,
19649701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.PHOTO_URI,
19659701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.PHOTO_THUMBNAIL_URI,
19669701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.CUSTOM_RINGTONE,
19679701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.HAS_PHONE_NUMBER,
19689701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.SEND_TO_VOICEMAIL,
19699701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.NUMBER,
19709701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.TYPE,
19719701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.LABEL,
19729701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                null, // PhoneLookup.NORMALIZED_NUMBER
19739701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        });
19749701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
19759701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        c.addRow(new Object[] {
19769701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                10L, // PhoneLookup._ID,
19779701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "key", // PhoneLookup.LOOKUP_KEY,
19789701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "name", // PhoneLookup.DISPLAY_NAME,
19799701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                123, // PhoneLookup.LAST_TIME_CONTACTED,
19809701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                456, // PhoneLookup.TIMES_CONTACTED,
19819701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.STARRED,
19829701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.IN_DEFAULT_DIRECTORY,
19839701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.IN_VISIBLE_GROUP,
19849701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1001, // PhoneLookup.PHOTO_FILE_ID,
19859701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1002, // PhoneLookup.PHOTO_ID,
19869701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "content://a/a", // PhoneLookup.PHOTO_URI,
19879701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "content://a/b", // PhoneLookup.PHOTO_THUMBNAIL_URI,
19889701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "content://a/c", // PhoneLookup.CUSTOM_RINGTONE,
19899701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.HAS_PHONE_NUMBER,
19909701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.SEND_TO_VOICEMAIL,
19919701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "1234", // PhoneLookup.NUMBER,
19929701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                1, // PhoneLookup.TYPE,
19939701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "label", // PhoneLookup.LABEL,
19949701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                "+1234", // PhoneLookup.NORMALIZED_NUMBER
19959701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        });
19969701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        rewritten = ContactsProvider2.rewriteCorpPhoneLookup(c);
19979701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(2, rewritten.getCount());
19989701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
19999701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        rewritten.moveToPosition(0);
20009701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        int column = 0;
20019701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1000000001L, rewritten.getLong(column++)); // We offset ID for corp contacts.
20029701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20039701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20049701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20059701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20069701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20079701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20089701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20099701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20109701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20119701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20129701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20139701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20149701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20159701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20169701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20179701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20189701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20199701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++));
20209701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
20219701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
20229701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        rewritten.moveToNext();
20239701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        column = 0;
20249701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1000000010L, rewritten.getLong(column++)); // With offset.
20259701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("key", rewritten.getString(column++));
20269701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("name", rewritten.getString(column++));
20279701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(123, rewritten.getInt(column++));
20289701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(456, rewritten.getInt(column++));
20299701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20309701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20319701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20329701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++)); // photo file id
20339701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++)); // photo id
20349701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("content://com.android.contacts/contacts_corp/10/display_photo",
20359701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                rewritten.getString(column++));
20369701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("content://com.android.contacts/contacts_corp/10/photo",
20379701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki                rewritten.getString(column++));
20389701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(null, rewritten.getString(column++)); // ringtone
20399701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20409701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20419701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("1234", rewritten.getString(column++));
20429701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals(1, rewritten.getInt(column++));
20439701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("label", rewritten.getString(column++));
20449701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki        assertEquals("+1234", rewritten.getString(column++));
20459701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki    }
20469701936fadaf55ef773dd07015b35f99fd5f8a91Makoto Onuki
2047653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    public void testPhoneUpdate() {
2048653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        ContentValues values = new ContentValues();
2049653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
2050653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
2051653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
20528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Hot", "Tamale");
2053653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "18004664411");
2054653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2055653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        Uri lookupUri1 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664411");
2056ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        Uri lookupUri2 = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, "8004664422");
2057ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri1, null, null));
2058ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri2, null, null));
2059653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2060653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
2061653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
2062653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
2063653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2064ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
2065ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
2066653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2067653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Setting number to null will remove the phone lookup record
2068653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
2069653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.putNull(Phone.NUMBER);
2070653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
2071653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2072ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
2073653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        assertEquals(0, getCount(lookupUri2, null, null));
2074653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2075653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        // Let's restore that phone lookup record
2076653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.clear();
2077653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664422");
2078653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov        mResolver.update(phoneUri, values, null, null);
2079ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(0, getCount(lookupUri1, null, null));
2080ac61fb8b20b05bb7a9af7c6d68bf8cdbdf675102Makoto Onuki        assertEquals(2, getCount(lookupUri2, null, null));
208181d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
2082653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov    }
2083653f73c9417ee0d2cf90e9aacd32848016747cf7Dmitri Plotnikov
2084e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    /** Tests if {@link Callable#CONTENT_URI} returns both phones and sip addresses. */
2085e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesQuery() {
20868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Meghan", "Knox");
2087e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long phoneId1 = ContentUris.parseId(insertPhoneNumber(rawContactId1, "18004664411"));
2088e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId1 = queryContactId(rawContactId1);
2089e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
20908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
2091e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long sipAddressId2 = ContentUris.parseId(
2092e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa                insertSipAddress(rawContactId2, "sip@example.com"));
2093e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        long contactId2 = queryContactId(rawContactId2);
2094e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
2095e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values1 = new ContentValues();
2096e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data._ID, phoneId1);
2097e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.RAW_CONTACT_ID, rawContactId1);
2098e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(RawContacts.CONTACT_ID, contactId1);
2099e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
2100e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.NUMBER, "18004664411");
2101e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Phone.TYPE, Phone.TYPE_HOME);
2102e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.putNull(Phone.LABEL);
2103e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values1.put(Contacts.DISPLAY_NAME, "Meghan Knox");
2104e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
2105e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        ContentValues values2 = new ContentValues();
2106e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data._ID, sipAddressId2);
2107e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.RAW_CONTACT_ID, rawContactId2);
2108e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(RawContacts.CONTACT_ID, contactId2);
2109e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
2110e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(SipAddress.SIP_ADDRESS, "sip@example.com");
2111e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        values2.put(Contacts.DISPLAY_NAME, "John Doe");
2112e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
2113e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertEquals(2, getCount(Callable.CONTENT_URI, null, null));
2114e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        assertStoredValues(Callable.CONTENT_URI, new ContentValues[] { values1, values2 });
2115e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
2116e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
2117e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    public void testCallablesFilterQuery() {
2118e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa        testPhonesFilterQueryInter(Callable.CONTENT_FILTER_URI);
2119e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa    }
2120e432023d408c461295e53c0593fabb2b4c17aeb3Daisuke Miyakawa
21214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testEmailsQuery() {
21224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
21234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "d");
21244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
21254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.LAST_TIME_CONTACTED, 12345);
21264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, 54321);
21274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, 1);
21284a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21294a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
21308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long rawContactId = ContentUris.parseId(rawContactUri);
21314a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Meghan", "Knox");
21338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri = insertEmail(rawContactId, "meghan@acme.com");
21348ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId = ContentUris.parseId(emailUri);
21354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21368ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
21374a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.clear();
21384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, emailId);
21394a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
21404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
21414a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21424a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "meghan@acme.com");
21434a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
21444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
21454a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Meghan Knox");
21464a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.CUSTOM_RINGTONE, "d");
21474a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, 1);
21484a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.LAST_TIME_CONTACTED, 12345);
21494a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.TIMES_CONTACTED, 54321);
21504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.STARRED, 1);
21514a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21528ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, values);
215348828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
21544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Email.CONTENT_URI, values, Data._ID, emailId);
21558ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
21568ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated email addresses.
21578ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri emailUri2 = insertEmail(rawContactId, "meghan@acme.com");
21588ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long emailId2 = ContentUris.parseId(emailUri2);
21598ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
21608ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, emailId2);
21618ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
21628ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = Email.CONTENT_URI.buildUpon()
21638ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
21648ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
21658ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
21668ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
21678ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId), values);
21688ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId), values);
21698ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(Email.CONTENT_URI, emailId2), values2);
21708ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, emailId2), values2);
21718ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
21728ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(Email.CONTENT_URI, new ContentValues[] {values, values2});
21738ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
21748ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
21758ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
21768ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
21778ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
21784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
21794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21805e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsLookupQuery() {
21818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale");
21824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        insertEmail(rawContactId, "tamale@acme.com");
21834a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
21845e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "tamale@acme.com");
21854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
21864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
21874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
21884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
21894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
21904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.putNull(Email.LABEL);
21914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(filterUri1, values);
21924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
219308768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "Ta<TaMale@acme.com>");
219408768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertStoredValues(filterUri2, values);
219508768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov
219608768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, "encilada@acme.com");
219708768a0f3434130fa46379c1bbfec93a19094939Dmitri Plotnikov        assertEquals(0, getCount(filterUri3, null, null));
21984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
21994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
22005e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    public void testEmailsFilterQuery() {
22018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
22028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
22035e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
22045e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId1, "tamale@acme.com");
22055e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Hot", "Tamale",
22078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
22085e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        insertEmail(rawContactId2, "tamale@acme.com");
22095e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22105e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tam");
22115e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        ContentValues values = new ContentValues();
22125e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Hot Tamale");
22135e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
22145e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.DATA, "tamale@acme.com");
22155e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.put(Email.TYPE, Email.TYPE_HOME);
22165e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        values.putNull(Email.LABEL);
22175e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
22185e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22195e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot");
22205e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri2, values);
22215e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
2222155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "hot tamale");
22235e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri3, values);
22245e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22251e530df9f7e496dc47f77d4323c89bd413b79b64Dmitri Plotnikov        Uri filterUri4 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "tamale@acme");
22265e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri4, values);
22275e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22285e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        Uri filterUri5 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "encilada");
22295e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov        assertEquals(0, getCount(filterUri5, null, null));
22305e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov    }
22315e99505757457d11d9388f6d04960e97fc776a59Dmitri Plotnikov
22327d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    /**
2233c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns addresses according to registration order.
2234c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
2235c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterDefaultSortOrder() {
22368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
2237c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
2238c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com");
2239c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address3@email.com");
2240c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2241c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
2242c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2243c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
2244c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v3 = new ContentValues();
2245c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
2246c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
2247c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
2248dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, new ContentValues[]{v1, v2, v3});
2249c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
2250c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
2251c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
2252c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     * Tests if ContactsProvider2 returns primary addresses before the other addresses.
2253c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa     */
2254c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    public void testEmailFilterPrimaryAddress() {
22558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
2256c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
2257c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        insertEmail(rawContactId1, "address2@email.com", true);
2258c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2259c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
2260c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2261c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
2262c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
2263c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
2264c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa        assertStoredValuesOrderly(filterUri, new ContentValues[] { v2, v1 });
2265c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    }
2266c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa
2267c591cc2ffecdd0038f787a133606752752294c13Daisuke Miyakawa    /**
22687d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * Tests if ContactsProvider2 has email address associated with a primary account before the
22697d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     * other address.
22707d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa     */
22717d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    public void testEmailFilterPrimaryAccount() {
22728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
22737d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId1, "account1@email.com");
22748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_2);
22757d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        insertEmail(rawContactId2, "account2@email.com");
22767d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v1 = new ContentValues();
22777d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v1.put(Email.ADDRESS, "account1@email.com");
22787d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        ContentValues v2 = new ContentValues();
22797d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        v2.put(Email.ADDRESS, "account2@email.com");
22807d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
22817d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
22828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
22838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_1.type)
22847d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
22857d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2 });
22867d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
22877d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
22888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
22898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, TestUtil.ACCOUNT_2.type)
22907d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
22917d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v2, v1 });
22927d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
22937d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        // Just with PRIMARY_ACCOUNT_NAME
22947d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
22958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_1.name)
22967d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
2297dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri3, new ContentValues[]{v1, v2});
22987d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
22997d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
23008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, TestUtil.ACCOUNT_2.name)
23017d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa                .build();
23027d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v2, v1 });
23037d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa    }
23047d82ae92714f2132e3a0971d844ae8cdf10d76e7Daisuke Miyakawa
2305dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
2306dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test emails with the same domain as primary account are ordered first.
2307dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
2308dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    public void testEmailFilterSameDomainAccountOrder() {
2309dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Account account = new Account("tester@email.com", "not_used");
23108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, account);
2311dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@testemail.com");
2312dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        insertEmail(rawContactId, "account1@email.com");
2313dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2314dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
2315dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account1@email.com");
2316dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2317dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri1 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("acc")
2318dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_NAME, account.name)
2319dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .appendQueryParameter(ContactsContract.PRIMARY_ACCOUNT_TYPE, account.type)
2320dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng                .build();
2321dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri1, v2, v1);
2322dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
2323dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2324dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    /**
2325dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     * Test "default" emails are sorted above emails used last.
2326dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng     */
2327c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterSuperPrimaryOverUsageSort() {
23288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
2329dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
2330dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
2331c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true, true);
2332dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2333dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Update account1 and account 2 to have higher usage.
2334dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
2335dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
2336dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
2337dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2338dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
2339dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
2340dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
2341dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2342dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
2343dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
2344dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertStoredValuesOrderly(filterUri, v3, v1, v2);
2345dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
2346dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
2347c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    /**
2348c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * Test primary emails are sorted below emails used last.
2349c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     *
2350c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * primary may be set without super primary.  Only super primary indicates "default" in the
2351c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     * contact ui.
2352c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng     */
2353c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    public void testEmailFilterUsageOverPrimarySort() {
23548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, TestUtil.ACCOUNT_1);
2355c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri1 = insertEmail(rawContactId, "account1@testemail.com");
2356c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final Uri emailUri2 = insertEmail(rawContactId, "account2@testemail.com");
2357c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        insertEmail(rawContactId, "account3@testemail.com", true);
2358c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
2359c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Update account1 and account 2 to have higher usage.
2360c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
2361c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri1);
2362c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, emailUri2);
2363c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
2364c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v1 = cv(Email.ADDRESS, "account1@testemail.com");
2365c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v2 = cv(Email.ADDRESS, "account2@testemail.com");
2366c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        final ContentValues v3 = cv(Email.ADDRESS, "account3@testemail.com");
2367c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
2368c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        // Test that account 3 is first even though account 1 and 2 have higher usage.
2369c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        Uri filterUri = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "acc");
2370c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng        assertStoredValuesOrderly(filterUri, v1, v2, v3);
2371c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng    }
2372c6e28121e4c522c31c96e0ea97b66012cc571160Chiao Cheng
237346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    /** Tests {@link DataUsageFeedback} correctly promotes a data row instead of a raw contact. */
237446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    public void testEmailFilterSortOrderWithFeedback() {
23758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
23764928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address1 = "address1@email.com";
23774928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId1, address1);
2378dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
23798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
23804928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address2 = "address2@email.com";
23814928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        insertEmail(rawContactId2, address2);
23824928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        String address3 = "address3@email.com";
23834928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        ContentUris.parseId(insertEmail(rawContactId2, address3));
238446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
238546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v1 = new ContentValues();
238646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
238746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v2 = new ContentValues();
238846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
238946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        ContentValues v3 = new ContentValues();
239046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
239146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
239246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
239346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri2 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
239446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
239546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_CALL)
239646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
239746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri3 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
239846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
239946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_LONG_TEXT)
240046abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
240146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        Uri filterUri4 = Email.CONTENT_FILTER_URI.buildUpon().appendPath("address")
240246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE,
240346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                        DataUsageFeedback.USAGE_TYPE_SHORT_TEXT)
240446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa                .build();
240546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v1, v2, v3 });
240646abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri2, new ContentValues[] { v1, v2, v3 });
240746abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v1, v2, v3 });
240846abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri4, new ContentValues[] { v1, v2, v3 });
240946abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
24104928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(address3, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, v3);
241146abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
2412dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
2413dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId1,
2414dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0
2415dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
2416dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rawContactId2,
2417dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 1
2418dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
2419dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
2420dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
2421dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // account3@email.com should be the first.
242246abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v3, v1, v2 });
242346abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa        assertStoredValuesOrderly(filterUri3, new ContentValues[] { v3, v1, v2 });
242446abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa    }
242546abbb56764add30cb6e6506f55d8dededc88113Daisuke Miyakawa
2426f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    /**
2427f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * Tests {@link DataUsageFeedback} correctly bucketize contacts using each
2428f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     * {@link DataUsageStatColumns#LAST_TIME_USED}
2429f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa     */
2430f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    public void testEmailFilterSortOrderWithOldHistory() {
24318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
2432f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId1 = ContentUris.parseId(insertEmail(rawContactId1, "address1@email.com"));
2433f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId2 = ContentUris.parseId(insertEmail(rawContactId1, "address2@email.com"));
2434f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId3 = ContentUris.parseId(insertEmail(rawContactId1, "address3@email.com"));
2435f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long dataId4 = ContentUris.parseId(insertEmail(rawContactId1, "address4@email.com"));
2436f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2437f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        Uri filterUri1 = Uri.withAppendedPath(Email.CONTENT_FILTER_URI, "address");
2438f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2439f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v1 = new ContentValues();
2440f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v1.put(Email.ADDRESS, "address1@email.com");
2441f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v2 = new ContentValues();
2442f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v2.put(Email.ADDRESS, "address2@email.com");
2443f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v3 = new ContentValues();
2444f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v3.put(Email.ADDRESS, "address3@email.com");
2445f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        ContentValues v4 = new ContentValues();
2446f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        v4.put(Email.ADDRESS, "address4@email.com");
2447f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2448f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        final ContactsProvider2 provider = (ContactsProvider2) getProvider();
2449f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2450f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long nowInMillis = System.currentTimeMillis();
2451f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long yesterdayInMillis = (nowInMillis - 24 * 60 * 60 * 1000);
2452f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long sevenDaysAgoInMillis = (nowInMillis - 7 * 24 * 60 * 60 * 1000);
2453f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        long oneYearAgoInMillis = (nowInMillis - 365L * 24 * 60 * 60 * 1000);
2454f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2455f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address4 is contacted just once yesterday.
2456f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId4),
2457f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, yesterdayInMillis);
2458f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2459f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address3 is contacted twice 1 week ago.
2460f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
2461f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
2462f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId3),
2463f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, sevenDaysAgoInMillis);
2464f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2465f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is contacted three times 1 year ago.
2466f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
2467f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
2468f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
2469f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
2470f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
2471f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, oneYearAgoInMillis);
2472f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2473f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // auto-complete should prefer recently contacted methods
2474f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v4, v3, v2, v1 });
2475f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2476f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address2 is contacted right now
2477f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId2),
2478f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
2479f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2480f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Now address2 is the most recently used address
2481f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v4, v3, v1 });
2482f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2483f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // Pretend address1 is contacted right now
2484f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        provider.updateDataUsageStat(Arrays.asList(dataId1),
2485f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa                DataUsageFeedback.USAGE_TYPE_LONG_TEXT, nowInMillis);
2486f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
2487f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        // address2 is preferred to address1 as address2 is used 4 times in total
2488f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa        assertStoredValuesOrderly(filterUri1, new ContentValues[] { v2, v1, v4, v3 });
2489f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa    }
2490f9648a03e88e2d1a91c616a20d903e4c9a2468e5Daisuke Miyakawa
24914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testPostalsQuery() {
24928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Alice", "Nextore");
24934a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri dataUri = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
24948ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId = ContentUris.parseId(dataUri);
24954a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
24968ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long contactId = queryContactId(rawContactId);
24974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
24984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data._ID, dataId);
24994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
25004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
25014a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, StructuredPostal.CONTENT_ITEM_TYPE);
25024a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(StructuredPostal.FORMATTED_ADDRESS, "1600 Amphiteatre Ave, Mountain View");
25034a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Alice Nextore");
25044a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
25058ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, values);
250648828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
250748828f54daafda2edb122258c4c6a7d2ca704128Dmitri Plotnikov                values);
25084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(StructuredPostal.CONTENT_URI, values, Data._ID, dataId);
25098ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
25108ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // Check if the provider detects duplicated addresses.
25118ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        Uri dataUri2 = insertPostalAddress(rawContactId, "1600 Amphiteatre Ave, Mountain View");
25128ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final long dataId2 = ContentUris.parseId(dataUri2);
25138ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final ContentValues values2 = new ContentValues(values);
25148ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values2.put(Data._ID, dataId2);
25158ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
25168ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        final Uri dedupeUri = StructuredPostal.CONTENT_URI.buildUpon()
25178ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .appendQueryParameter(ContactsContract.REMOVE_DUPLICATE_ENTRIES, "true")
25188ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                .build();
25198ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
25208ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // URI with ID should return a correct result.
25218ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId),
25228ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values);
25238ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId), values);
25248ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(StructuredPostal.CONTENT_URI, dataId2),
25258ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa                values2);
25268ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(ContentUris.withAppendedId(dedupeUri, dataId2), values2);
25278ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
25288ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(StructuredPostal.CONTENT_URI, new ContentValues[] {values, values2});
25298ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa
25308ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // If requested to remove duplicates, the query should return just one result,
25318ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        // whose _ID won't be deterministic.
25328ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        values.remove(Data._ID);
25338ead0dc62d0031a22af0d14c7ed05893507893c9Daisuke Miyakawa        assertStoredValues(dedupeUri, values);
25344a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
25354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
25368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testDataContentUriInvisibleQuery() {
25378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues values = new ContentValues();
25388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final long contactId = createContact(values, "John", "Doe",
25398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
25408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                        StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
25418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri uri = Data.CONTENT_URI.buildUpon().
25438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                appendQueryParameter(Data.VISIBLE_CONTACTS_ONLY, "true").build();
25448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(4, getCount(uri, null, null));
25458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(contactId);
25478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(uri, null, null));
25498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
25508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25519273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell    public void testInDefaultDirectoryData() {
25529273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        final ContentValues values = new ContentValues();
25539273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        final long contactId = createContact(values, "John", "Doe",
25549273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
25559273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                StatusUpdates.CAPABILITY_HAS_CAMERA);
25569273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell
25579273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        final StringBuilder query = new StringBuilder()
25589273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                .append(Data.MIMETYPE).append("='").append(Email.CONTENT_ITEM_TYPE)
25599273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                .append("' AND ").append(Email.DATA).append("=? AND ")
25609273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                .append(Contacts.IN_DEFAULT_DIRECTORY).append("=1");
25619273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell
25629273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        assertEquals(1,
25639273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                getCount(Email.CONTENT_URI, query.toString(), new String[]{"goog411@acme.com"}));
25649273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell
25659273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        // Fire!
25669273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        markInvisible(contactId);
25679273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell
25689273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        // Verify: making a contact visible changes the IN_DEFAULT_DIRECTORY data value.
25699273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell        assertEquals(0,
25709273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell                getCount(Email.CONTENT_URI, query.toString(), new String[]{"goog411@acme.com"}));
25719273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell    }
25729273f0155a8dafa61527ef8a71f3e0eaff3e4b8aBrian Attwell
25738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesQuery() {
25748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
25758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
25768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
25788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
25798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
25818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
25828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
25838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
25848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
25858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
25868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
25888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
25898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
25908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
25918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
25928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
25938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri0 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "");
25958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri0, null, null));
25968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
25978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
25988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2);
25998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
26018f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2);
26028f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26038f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale@ac");
26048f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2);
26058f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26068f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "510");
26078f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv1, cv2);
26088f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26098f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "cold");
26108f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri5, null, null));
26118f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26128f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
26138f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
26148f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri6, null, null));
26158f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26168f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Contactables.CONTENT_URI;
26178f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri7, cv1, cv2);
26188f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
26198f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26208f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    public void testContactablesMultipleQuery() {
26218f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Hot",
26238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamale");
26248f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId, "510-123-5769");
26258f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "tamale@acme.com");
26268f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId, "hot@google.com");
26278f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "Cold",
26298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "Tamago");
26308f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId2, "eggs@farmers.org");
26318f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe");
26338f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertPhoneNumber(rawContactId3, "518-354-1111");
26348f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        insertEmail(rawContactId3, "doeadeer@afemaledeer.com");
26358f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26368f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv1 = new ContentValues();
26378f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Contacts.DISPLAY_NAME, "Hot Tamale");
26388f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
26398f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.DATA, "tamale@acme.com");
26408f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.put(Email.TYPE, Email.TYPE_HOME);
26418f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv1.putNull(Email.LABEL);
26428f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26438f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv2 = new ContentValues();
26448f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Contacts.DISPLAY_NAME, "Hot Tamale");
26458f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
26468f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.DATA, "510-123-5769");
26478f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.put(Phone.TYPE, Phone.TYPE_HOME);
26488f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv2.putNull(Phone.LABEL);
26498f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26508f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv3 = new ContentValues();
26518f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Contacts.DISPLAY_NAME, "Hot Tamale");
26528f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
26538f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.DATA, "hot@google.com");
26548f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.put(Email.TYPE, Email.TYPE_HOME);
26558f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv3.putNull(Email.LABEL);
26568f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26578f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv4 = new ContentValues();
26588f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Contacts.DISPLAY_NAME, "Cold Tamago");
26598f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
26608f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.DATA, "eggs@farmers.org");
26618f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.put(Email.TYPE, Email.TYPE_HOME);
26628f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv4.putNull(Email.LABEL);
26638f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26648f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv5 = new ContentValues();
26658f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Contacts.DISPLAY_NAME, "John Doe");
26668f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
26678f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.DATA, "doeadeer@afemaledeer.com");
26688f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.put(Email.TYPE, Email.TYPE_HOME);
26698f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv5.putNull(Email.LABEL);
26708f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26718f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final ContentValues cv6 = new ContentValues();
26728f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Contacts.DISPLAY_NAME, "John Doe");
26738f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
26748f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.DATA, "518-354-1111");
26758f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.put(Phone.TYPE, Phone.TYPE_HOME);
26768f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        cv6.putNull(Phone.LABEL);
26778f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26788f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri1 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tamale");
26798f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26808f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri1, cv1, cv2, cv3);
26818f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26828f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri2 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "hot");
26838f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri2, cv1, cv2, cv3);
26848f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26858f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri3 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "tam");
26868f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri3, cv1, cv2, cv3, cv4);
26878f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26888f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri4 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "518");
26898f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri4, cv5, cv6);
26908f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26918f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri5 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "doe");
26928f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri5, cv5, cv6);
26938f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26948f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri6 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI, "51");
26958f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri6, cv1, cv2, cv3, cv5, cv6);
26968f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
26978f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri7 = Uri.withAppendedPath(Contactables.CONTENT_FILTER_URI,
26988f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                "tamale@google");
26998f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertEquals(0, getCount(filterUri7, null, null));
27008f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
27018f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri8 = Contactables.CONTENT_URI;
27028f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri8, cv1, cv2, cv3, cv4, cv5, cv6);
27038f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
27048f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // test VISIBLE_CONTACTS_ONLY boolean parameter
27058f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        final Uri filterUri9 = filterUri6.buildUpon().appendQueryParameter(
27068f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee                Contactables.VISIBLE_CONTACTS_ONLY, "true").build();
27078f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv1, cv2, cv3, cv5, cv6);
27088f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        // mark Hot Tamale as invisible - cv1, cv2, and cv3 should no longer be in the cursor
27098f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        markInvisible(queryContactId(rawContactId));
27108f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee        assertStoredValues(filterUri9, cv5, cv6);
27118f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee    }
27128f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
27138f8b122c7556350d94c2e349b3093024b0205d8dYorke Lee
27144a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    public void testQueryContactData() {
27154a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
27164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2717aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2718d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
27194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
27204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
27214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertStoredValues(contactUri, values);
27224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertSelection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
27234a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
27244a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
27250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testQueryContactWithStatusUpdate() {
27264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
27274a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long contactId = createContact(values, "John", "Doe",
2728aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2729aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
273082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2731aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        values.put(Contacts.CONTACT_CHAT_CAPABILITY, StatusUpdates.CAPABILITY_HAS_CAMERA);
2732ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
2733ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
2734ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertSelectionWithProjection(Contacts.CONTENT_URI, values, Contacts._ID, contactId);
27354a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
27364a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2737a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByName() {
27384a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values = new ContentValues();
273948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2740aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2741d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2742aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
274348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
274448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        ContentValues nameValues = new ContentValues();
274548786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.GIVEN_NAME, "Stu");
274648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        nameValues.put(StructuredName.FAMILY_NAME, "Goulash");
27473b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "goo");
27483b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "LASH");
27498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, nameValues);
275048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
275148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
275282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
275348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2754ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goulash");
2755ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
27564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
275748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        assertContactFilter(contactId, "goolash");
27583b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        assertContactFilter(contactId, "lash");
275948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
2760a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
27613b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov
27623b10d3a1ed1052dcdf529da370cb71b74164b158Dmitri Plotnikov        // Phonetic name with given/family reversed should not match
2763a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("lashgoo");
27647ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
27657ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.clear();
27667ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_FAMILY_NAME, "ga");
27677ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        nameValues.put(StructuredName.PHONETIC_GIVEN_NAME, "losh");
27687ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
27697ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        mResolver.update(nameUri, nameValues, null, null);
27707ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
27717ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov        assertContactFilter(contactId, "galosh");
27727ceafd016eb07d2de808d18cd5a9463efaee781dDmitri Plotnikov
2773a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2774a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2775a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2776a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByEmailAddress() {
2777a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2778a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2779a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2780a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2781a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2782a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
27838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2784a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2785a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2786a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2787a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2788a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "goog411@acme.com");
2789a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2790a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2791a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog");
2792a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411");
2793a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@");
2794a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme");
2795a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "goog411@acme.com");
2796a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2797a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@acme.combo");
2798a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goog411@le.com");
2799a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("goolish");
2800a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
2801a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2802a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    public void testQueryContactFilterByPhoneNumber() {
2803a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        ContentValues values = new ContentValues();
2804a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long rawContactId = createRawContact(values, "18004664411",
2805a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
2806a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
2807a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov                StatusUpdates.CAPABILITY_HAS_VOICE);
2808a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
28098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "James", "Bond");
2810a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2811a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
2812a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
2813a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2814a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, "18004664411");
2815a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertStoredValuesWithProjection(filterUri1, values);
2816a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2817a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "18004664411");
2818a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "1800466");
2819a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "+18004664411");
2820a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilter(contactId, "8004664411");
2821a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
2822a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("78004664411");
2823a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("18004664412");
2824a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov        assertContactFilterNoResult("8884664411");
28254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
28264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
28272f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa    /**
28282f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * Checks ContactsProvider2 works well with strequent Uris. The provider should return starred
28292f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     * contacts and frequently used contacts.
28302f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa     */
2831ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactStrequent() {
28324a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
28332f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String email1 = "a@acme.com";
2834a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber1 = "18004664411";
28352f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted1 = 0;
2836a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        createContact(values1, "Noah", "Tever", phoneNumber1,
28372f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                email1, StatusUpdates.OFFLINE, timesContacted1, 0, 0,
2838d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
28394928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final String phoneNumber2 = "18004664412";
28404a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
28414928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        createContact(values2, "Sam", "Times", phoneNumber2,
2842aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "b@acme.com", StatusUpdates.INVISIBLE, 3, 0, 0,
2843aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
28444a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values3 = new ContentValues();
28452f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final String phoneNumber3 = "18004664413";
28462f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        final int timesContacted3 = 5;
28472f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        createContact(values3, "Lotta", "Calling", phoneNumber3,
28482f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, timesContacted3, 0, 0,
2849d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO);
28504a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values4 = new ContentValues();
28519dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        final long rawContactId4 = createRawContact(values4, "Fay", "Veritt", null,
2852aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0,
2853d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_VIDEO | StatusUpdates.CAPABILITY_HAS_VOICE);
28544a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
28552f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Starred contacts should be returned. TIMES_CONTACTED should be ignored and only data
28562f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // usage feedback should be used for "frequently contacted" listing.
28572f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(Contacts.CONTENT_STREQUENT_URI, values4);
28582f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
28592f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Send feedback for the 3rd phone number, pretending we called that person via phone.
28604928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
28612f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
28622f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 3rd contact should be shown after starred one.
28632f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
28642f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                new ContentValues[] { values4, values3 });
28652f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
28664928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
28672f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // Twice.
28684928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
28692f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
28702f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        // After the feedback, 1st and 3rd contacts should be shown after starred one.
28712f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
28724928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                new ContentValues[] { values4, values1, values3 });
28732f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa
28749dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // With phone-only parameter, 1st and 4th contacts shouldn't be returned because:
28759dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 1st: feedbacks are only about email, not about phone call.
28769dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        // 4th: it has no phone number though starred.
28772f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        Uri phoneOnlyStrequentUri = Contacts.CONTENT_STREQUENT_URI.buildUpon()
28782f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true")
28792f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa                .build();
28809dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] { values3 });
28819dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa
2882a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Now the 4th contact has three phone numbers, one of which is called twice and
2883a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // the other once
2884a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber4 = "18004664414";
2885a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber5 = "18004664415";
2886a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final String phoneNumber6 = "18004664416";
2887a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber4);
2888a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber5);
2889a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        insertPhoneNumber(rawContactId4, phoneNumber6);
2890a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values3.put(Phone.NUMBER, phoneNumber3);
2891a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values4.put(Phone.NUMBER, phoneNumber4);
2892a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2893a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber5, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2894a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber5, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2895a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        sendFeedback(phoneNumber6, DataUsageFeedback.USAGE_TYPE_CALL, values4);
2896a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2897a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Create a ContentValues object representing the second phone number of contact 4
2898a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final ContentValues values5 = new ContentValues(values4);
2899a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values5.put(Phone.NUMBER, phoneNumber5);
2900a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2901a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Create a ContentValues object representing the third phone number of contact 4
2902a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        final ContentValues values6 = new ContentValues(values4);
2903a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values6.put(Phone.NUMBER, phoneNumber6);
2904a176ed4c42330e64d0246a10374507c862cec0deYorke Lee
2905a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // Phone only strequent should return all phone numbers belonging to the 4th contact,
2906a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        // and then contact 3.
2907a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] {values5, values6,
2908a176ed4c42330e64d0246a10374507c862cec0deYorke Lee                values4, values3});
29094928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
29104928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // Send feedback for the 2rd phone number, pretending we send the person a SMS message.
29114928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        sendFeedback(phoneNumber2, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
29124928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
29134928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        // SMS feedback shouldn't affect phone-only results.
2914a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        assertStoredValuesOrderly(phoneOnlyStrequentUri, new ContentValues[] {values5, values6,
2915a176ed4c42330e64d0246a10374507c862cec0deYorke Lee                values4, values3});
29164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
2917a176ed4c42330e64d0246a10374507c862cec0deYorke Lee        values4.remove(Phone.NUMBER);
2918ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_STREQUENT_FILTER_URI, "fay");
29192f830d3bb66f780937203e9738e046841a070e73Daisuke Miyakawa        assertStoredValues(filterUri, values4);
29204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
29214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
292263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    public void testQueryContactStrequentFrequentOrder() {
292363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare test data
29248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContact(mResolver);
292563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1 = ContentUris.parseId(insertPhoneNumber(rid1, "1"));
292663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did1e = ContentUris.parseId(insertEmail(rid1, "1@email.com"));
292763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
29288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContact(mResolver);
292963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did2 = ContentUris.parseId(insertPhoneNumber(rid2, "2"));
293063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
29318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContact(mResolver);
293263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did3 = ContentUris.parseId(insertPhoneNumber(rid3, "3"));
293363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
29348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContact(mResolver);
293563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did4 = ContentUris.parseId(insertPhoneNumber(rid4, "4"));
293663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
29378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid5 = RawContactUtil.createRawContact(mResolver);
293863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did5 = ContentUris.parseId(insertPhoneNumber(rid5, "5"));
293963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
29408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid6 = RawContactUtil.createRawContact(mResolver);
294163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long did6 = ContentUris.parseId(insertPhoneNumber(rid6, "6"));
294263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2943d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long rid7 = RawContactUtil.createRawContact(mResolver);
2944d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long did7 = ContentUris.parseId(insertPhoneNumber(rid7, "7"));
2945d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2946d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long rid8 = RawContactUtil.createRawContact(mResolver);
2947d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long did8 = ContentUris.parseId(insertPhoneNumber(rid8, "8"));
2948d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
294963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid1 = queryContactId(rid1);
295063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid2 = queryContactId(rid2);
295163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid3 = queryContactId(rid3);
295263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid4 = queryContactId(rid4);
295363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid5 = queryContactId(rid5);
295463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long cid6 = queryContactId(rid6);
2955d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long cid7 = queryContactId(rid7);
2956d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long cid8 = queryContactId(rid8);
295763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
295863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Make sure they aren't aggregated.
2959d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        EvenMoreAsserts.assertUnique(cid1, cid2, cid3, cid4, cid5, cid6, cid7, cid8);
296063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
296163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Prepare the clock
296263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        sMockClock.install();
296363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
296463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // We check the timestamp in SQL, which doesn't know about the MockClock.  So we need to
296563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // use the  actual (roughly) time.
296663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
296763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        final long nowInMillis = System.currentTimeMillis();
2968d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long oneDayAgoInMillis = (nowInMillis - 24L * 60 * 60 * 1000);
2969d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long fourDaysAgoInMillis = (nowInMillis - 4L * 24 * 60 * 60 * 1000);
2970d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long eightDaysAgoInMillis = (nowInMillis - 8L * 24 * 60 * 60 * 1000);
2971d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long fifteenDaysAgoInMillis = (nowInMillis - 15L * 24 * 60 * 60 * 1000);
2972d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // All contacts older than 30 days will not be included in frequents
2973d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        final long thirtyOneDaysAgoInMillis = (nowInMillis - 31L * 24 * 60 * 60 * 1000);
297463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2975d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 30 days old
2976d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(thirtyOneDaysAgoInMillis);
297763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
297863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1, did2);
297963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did1);
298063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2981d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 14 days old
2982d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(fifteenDaysAgoInMillis);
298363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
298463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3, did4);
298563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did3);
298663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2987d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 7 days old
2988d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(eightDaysAgoInMillis);
298963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
299063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5, did6);
299163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did5);
299263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
299363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Contact cid1 again, but it's an email, not a phone call.
299463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1e);
299563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
2996d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered more than 3 days old
2997d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(fourDaysAgoInMillis);
2998d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
2999d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did7);
3000d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did7);
3001d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
3002d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
3003d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Contacts in this bucket are considered less than 3 days old
3004d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(oneDayAgoInMillis);
3005d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
3006d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did8);
3007d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
3008d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(nowInMillis);
3009d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
301063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- The regular frequent, which is contact based.
3011d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // Note because we contacted cid1 8 days ago, it's been contacted 3 times, so it comes
3012d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // before cid5 and cid6, which were contacted at the same time.
3013d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // cid2 will not show up because it was contacted more than 30 days ago
3014d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee
301563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI,
3016d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid8),
3017d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid7),
301863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid1),
301963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid5),
302063630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid6),
302163630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Contacts._ID, cid3),
3022d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Contacts._ID, cid4));
302363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
302463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Check the order -- phone only frequent, which is data based.
302563630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // Note this is based on data, and only looks at phone numbers, so the order is different
302663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        // now.
3027d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        // did1, did2 will not show up because they were used to make calls more than 30 days ago.
302863630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki        assertStoredValuesOrderly(Contacts.CONTENT_STREQUENT_URI.buildUpon()
302963630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                    .appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "1").build(),
3030d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did8),
3031d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did7),
303263630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did5),
303363630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did6),
303463630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki                cv(Data._ID, did3),
3035d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee                cv(Data._ID, did4));
303663630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki    }
303763630bc7f962fd2b6f2c1bc41cbed45a8bc354baMakoto Onuki
303845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    /**
303945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * Checks ContactsProvider2 works well with frequent Uri. The provider should return frequently
304045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     * contacted person ordered by number of times contacted.
304145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa     */
304245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    public void testQueryContactFrequent() {
304345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values1 = new ContentValues();
304445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email1 = "a@acme.com";
304545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values1, "Noah", "Tever", "18004664411",
304645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
304745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values2 = new ContentValues();
304845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String email2 = "b@acme.com";
304945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values2, "Sam", "Times", "18004664412",
305045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
305145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values3 = new ContentValues();
305245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        final String phoneNumber3 = "18004664413";
3053363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        final long contactId3 = createContact(values3, "Lotta", "Calling", phoneNumber3,
3054363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                "c@acme.com", StatusUpdates.AWAY, 0, 1, 0, 0);
305545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        ContentValues values4 = new ContentValues();
305645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        createContact(values4, "Fay", "Veritt", "18004664414",
305745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                "d@acme.com", StatusUpdates.AVAILABLE, 0, 1, 0, 0);
305845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
305945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
306045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
306145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, values1);
306245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
306345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Pretend email was sent to the address twice.
306445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
306545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
306645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
306745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
306845ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
306945ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        // Three times
307045ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
307145ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
307245ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        sendFeedback(phoneNumber3, DataUsageFeedback.USAGE_TYPE_CALL, values3);
307345ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
307445ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
307545ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
3076363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
3077363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        // Test it works with selection/selectionArgs
3078363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
3079363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
3080363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values2, values1});
3081363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
3082363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
3083363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3});
3084363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa
3085363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        values3.put(Contacts.STARRED, 0);
3086363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertEquals(1,
3087363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                mResolver.update(Uri.withAppendedPath(Contacts.CONTENT_URI,
3088363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                        String.valueOf(contactId3)),
3089363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                values3, null, null));
3090363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
3091363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"0"},
3092363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {values3, values2, values1});
3093363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa        assertStoredValues(Contacts.CONTENT_FREQUENT_URI,
3094363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                Contacts.STARRED + "=?", new String[] {"1"},
3095363bdaba2994539e1a3a2342a9fcf223604d69eaDaisuke Miyakawa                new ContentValues[] {});
309645ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa    }
309745ae7eaf0e2c9459ccbeeb5eb5977f055c4ed8ecDaisuke Miyakawa
309880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    public void testQueryContactFrequentExcludingInvisible() {
309980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values1 = new ContentValues();
310080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email1 = "a@acme.com";
310180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
310280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
310380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        ContentValues values2 = new ContentValues();
310480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final String email2 = "b@acme.com";
310580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        final long cid2 = createContact(values2, "Sam", "Times", "18004664412",
310680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki                email2, StatusUpdates.INVISIBLE, 0, 0, 0, 0);
310780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
310880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
310980628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        sendFeedback(email2, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values2);
311080628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
311180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // First, we have two contacts in frequent.
311280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values2, values1});
311380628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
311480628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Contact 2 goes invisible.
311580628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        markInvisible(cid2);
311680628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
311780628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        // Now we have only 1 frequent.
311880628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki        assertStoredValues(Contacts.CONTENT_FREQUENT_URI, new ContentValues[] {values1});
3119216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3120216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    }
3121216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3122216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee    public void testQueryDataUsageStat() {
3123216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        ContentValues values1 = new ContentValues();
3124216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final String email1 = "a@acme.com";
3125216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final long cid1 = createContact(values1, "Noah", "Tever", "18004664411",
3126216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                email1, StatusUpdates.OFFLINE, 0, 0, 0, 0);
3127216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3128216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.install();
3129216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(100);
3130216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3131216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
3132216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3133216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 1, 100);
3134216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3135216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(111);
3136216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_LONG_TEXT, values1);
3137216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3138216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 2, 111);
3139216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3140216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(123);
3141216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, values1);
3142216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3143216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 3, 123);
3144216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3145216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeLongText = Data.CONTENT_URI.buildUpon().appendQueryParameter(
3146216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_LONG_TEXT).build();
3147216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3148216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeLongText, "a@acme.com", 2, 111);
3149216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3150216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sMockClock.setCurrentTimeMillis(200);
3151216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
3152216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
3153216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        sendFeedback(email1, DataUsageFeedback.USAGE_TYPE_CALL, values1);
3154216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3155216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(Data.CONTENT_URI, "a@acme.com", 6, 200);
3156216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3157216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        final Uri dataUriWithUsageTypeCall = Data.CONTENT_URI.buildUpon().appendQueryParameter(
3158216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee                DataUsageFeedback.USAGE_TYPE, DataUsageFeedback.USAGE_TYPE_CALL).build();
3159216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee
3160216c434537d05a691add4e22ba3a9d958c976c1eYorke Lee        assertDataUsageCursorContains(dataUriWithUsageTypeCall, "a@acme.com", 3, 200);
316180628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki    }
316280628945e7e41bb9363c2fbbd2938890b9217792Makoto Onuki
3163ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov    public void testQueryContactGroup() {
31644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long groupId = createGroup(null, "testGroup", "Test Group");
31654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
31664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values1 = new ContentValues();
31674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values1, "Best", "West", "18004664411",
3168aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "west@acme.com", StatusUpdates.OFFLINE, 0, 0, groupId,
3169aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
31704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
31714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        ContentValues values2 = new ContentValues();
31724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        createContact(values2, "Rest", "East", "18004664422",
3173aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                "east@acme.com", StatusUpdates.AVAILABLE, 0, 0, 0,
3174aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
31754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
3176ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri1 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
31774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Cursor c = mResolver.query(filterUri1, null, null, null, Contacts._ID);
31784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
31794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.moveToFirst();
31804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertCursorValues(c, values1);
31814a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
31824a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
3183ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri2 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Test Group");
31844a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri2, null, Contacts.DISPLAY_NAME + "=?",
31854a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov                new String[] { "Best West" }, Contacts._ID);
31864a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
31874a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
31884a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
3189ff2de103f7e3eeeff4665ef63f07460fef053d6dDmitri Plotnikov        Uri filterUri3 = Uri.withAppendedPath(Contacts.CONTENT_GROUP_URI, "Next Group");
31904a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c = mResolver.query(filterUri3, null, null, null, Contacts._ID);
31914a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(0, c.getCount());
31924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        c.close();
31933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
31943cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
319536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    private void expectSecurityException(String failureMessage, Uri uri, String[] projection,
319636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            String selection, String[] selectionArgs, String sortOrder) {
319724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = null;
319824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
319936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            c = mResolver.query(uri, projection, selection, selectionArgs, sortOrder);
320036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail(failureMessage);
320124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
320236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            // The security exception is expected to occur because we're missing a permission.
320324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } finally {
320424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            if (c != null) {
320524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                c.close();
320624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            }
320724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
320836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
320936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
321036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testQueryProfileRequiresReadPermission() {
321136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
321236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
321336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        createBasicProfileContact(new ContentValues());
321436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
321536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Case 1: Retrieving profile contact.
321636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
321736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile without READ_PROFILE access should fail.",
321836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI, null, null, null, Contacts._ID);
321924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
322024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieving profile data.
322136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
322236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile data without READ_PROFILE access should fail.",
322336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
322436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
322524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
322624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieving profile entities.
322736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
322836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile entities without READ_PROFILE access should fail.",
322936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon()
323036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entities").build(), null, null, null, Contacts._ID);
323124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
323224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
323324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByContactIdRequiresReadPermission() {
323424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
323524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
323624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
323724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
323824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
323924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // A query for the profile contact by ID should fail.
324036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
324136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the profile by contact ID without READ_PROFILE access should fail.",
324236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
324336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, Contacts._ID);
324424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
324524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
324624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileByRawContactIdRequiresReadPermission() {
324724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
324824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
324924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the raw contact.
325024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
325136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
325236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
325336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(RawContacts.CONTENT_URI,
325436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        profileRawContactId), null, null, null, RawContacts._ID);
325524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
325624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
325724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileRawContactRequiresReadPermission() {
325824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
325924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
326024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the profile's raw contact data.
326124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
326224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
326324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 1: Retrieve the overall raw contact set for the profile.
326436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
326536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw contact profile without READ_PROFILE access should fail.",
326636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, null, null, null, null);
326724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
326824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 2: Retrieve the raw contact profile data for the inserted raw contact ID.
326936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
327036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile data without READ_PROFILE access should fail.",
327136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
327236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
327336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("data").build(), null, null, null, null);
327424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
327524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Case 3: Retrieve the raw contact profile entity for the inserted raw contact ID.
327636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
327736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the raw profile entities without READ_PROFILE access should fail.",
327836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
327936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
328036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath("entity").build(), null, null, null, null);
328124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
328224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
328324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataByDataIdRequiresReadPermission() {
328424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
328524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor c = mResolver.query(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
328624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                new String[]{Data._ID, Data.MIMETYPE}, null, null, null);
328724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(4, c.getCount());  // Photo, phone, email, name.
328824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.moveToFirst();
328924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileDataId = c.getLong(0);
329024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        c.close();
329124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
329224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve the data
329324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
329436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
329536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
329636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(Data.CONTENT_URI, profileDataId),
329736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
329824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
329924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
330024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileDataRequiresReadPermission() {
330124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
330224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
330324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Remove profile read permission and attempt to retrieve all profile data.
330424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
330536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
330636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying for the data in the profile without READ_PROFILE access should fail.",
330736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
330836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
330924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
331024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
331124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileRequiresWritePermission() {
331224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
331324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
331424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a non-profile contact should be fine.
331524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(new ContentValues());
331624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
331724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Creating a profile contact should throw an exception.
331824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
331924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            createBasicProfileContact(new ContentValues());
332024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Creating a profile contact should fail without WRITE_PROFILE access.");
332124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
332224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
332324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
332424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
332524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testInsertProfileDataRequiresWritePermission() {
332624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
332724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
332824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
332924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        try {
333024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            insertEmail(profileRawContactId, "foo@bar.net", false);
333124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            fail("Inserting data into a profile contact should fail without WRITE_PROFILE access.");
333224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        } catch (SecurityException expected) {
333324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        }
333424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
333524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
33366ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    public void testUpdateDataDoesNotRequireProfilePermission() {
33376ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.READ_PROFILE");
33386ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mActor.removePermissions("android.permission.WRITE_PROFILE");
33396ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
33406ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Create a non-profile contact.
33418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver, "Domo", "Arigato");
33426ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        long dataId = getStoredLongValue(Data.CONTENT_URI,
33436ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data.RAW_CONTACT_ID + "=? AND " + Data.MIMETYPE + "=?",
33446ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(rawContactId), StructuredName.CONTENT_ITEM_TYPE},
33456ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                Data._ID);
33466ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
33476ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Updates its name using a selection.
33486ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        ContentValues values = new ContentValues();
33496ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.GIVEN_NAME, "Bob");
33506ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        values.put(StructuredName.FAMILY_NAME, "Blob");
33516ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
33526ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro                new String[]{String.valueOf(dataId)});
33536ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
33546ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        // Check that the update went through.
33556ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro        assertStoredValues(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), values);
33566ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro    }
33576ae89770d8047852b6a1f6fb3cbac812910aa476Dave Santoro
33585d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro    public void testQueryContactThenProfile() {
335924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
336024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
336124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileContactId = queryContactId(profileRawContactId);
336224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
336324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
336424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createBasicNonProfileContact(nonProfileValues);
336524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileContactId = queryContactId(nonProfileRawContactId);
336624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
33675d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Contacts.CONTENT_URI, nonProfileValues);
336824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertSelection(Contacts.CONTENT_URI, nonProfileValues, Contacts._ID, nonProfileContactId);
33695d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro
33705d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
337124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
337224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
337324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryContactExcludeProfile() {
337424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a profile contact (it should not be returned by the general contact URI).
337524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
337624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
337724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Create a non-profile contact - this should be returned.
337824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nonProfileValues = new ContentValues();
337924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicNonProfileContact(nonProfileValues);
338024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
338124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Contacts.CONTENT_URI, new ContentValues[] {nonProfileValues});
338224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
338324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
338424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfile() {
338524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
338624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
338724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
338824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI, profileValues);
338924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
339024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
339124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private ContentValues[] getExpectedProfileDataValues() {
339224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected photo data values (only field is the photo BLOB, which we can't check).
339324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues photoRow = new ContentValues();
339424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        photoRow.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
339524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
339624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected phone data values.
339724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues phoneRow = new ContentValues();
339824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
339924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        phoneRow.put(Phone.NUMBER, "18005554411");
340024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
340124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected email data values.
340224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues emailRow = new ContentValues();
340324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
340424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        emailRow.put(Email.ADDRESS, "mia.prophyl@acme.com");
340524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
340624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // Expected name data values.
340724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues nameRow = new ContentValues();
340824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
340924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.DISPLAY_NAME, "Mia Prophyl");
341024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.GIVEN_NAME, "Mia");
341124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nameRow.put(StructuredName.FAMILY_NAME, "Prophyl");
341224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
341324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return new ContentValues[]{photoRow, phoneRow, emailRow, nameRow};
341424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
341524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
341624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileData() {
341724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
341824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
341924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
342024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
342124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
342224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
342324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryProfileEntities() {
342424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
342524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
342624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("entities").build(),
342724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
342824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
342924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
343024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfile() {
343124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
343224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(profileValues);
343324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
343424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
343524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
343624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, profileValues);
343724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
343824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
343924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileById() {
344024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        ContentValues profileValues = new ContentValues();
344124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(profileValues);
344224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
344324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        // The raw contact view doesn't include the photo ID.
344424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.remove(Contacts.PHOTO_ID);
344524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
344624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId), profileValues);
344724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
344824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
344924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileData() {
345024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
345124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
345224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
345324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
345424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("data").build(), getExpectedProfileDataValues());
345524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
345624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
345724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryRawProfileEntity() {
345824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createBasicProfileContact(new ContentValues());
345924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
346024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(ContentUris.withAppendedId(
346124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                Profile.CONTENT_RAW_CONTACTS_URI, profileRawContactId).buildUpon()
346224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                .appendPath("entity").build(), getExpectedProfileDataValues());
346324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
346424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
346524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryDataForProfile() {
346624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
346724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
346824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertStoredValues(Profile.CONTENT_URI.buildUpon().appendPath("data").build(),
346924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                getExpectedProfileDataValues());
347024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
347124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
3472cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    public void testUpdateProfileRawContact() {
3473cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        createBasicProfileContact(new ContentValues());
3474cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        ContentValues updatedValues = new ContentValues();
3475cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.SEND_TO_VOICEMAIL, 0);
3476cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.CUSTOM_RINGTONE, "rachmaninoff3");
3477cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        updatedValues.put(RawContacts.STARRED, 1);
3478cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        mResolver.update(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues, null, null);
3479cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
3480cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, updatedValues);
3481cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro    }
3482cce1c9cf029f40b62955f4b545f94c993daefbd2Dave Santoro
3483a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    public void testInsertProfileWithDataSetTriggersAccountCreation() {
3484a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that we have no profile raw contacts.
3485a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, new ContentValues[]{});
3486a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
3487a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Insert a profile record with a new data set.
3488a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        Account account = new Account("a", "b");
3489a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        String dataSet = "c";
34908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri profileUri = TestUtil.maybeAddAccountQueryParameters(Profile.CONTENT_RAW_CONTACTS_URI,
34918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account)
3492a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro                .buildUpon().appendQueryParameter(RawContacts.DATA_SET, dataSet).build();
3493a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        ContentValues values = new ContentValues();
3494a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        long rawContactId = ContentUris.parseId(mResolver.insert(profileUri, values));
3495a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        values.put(RawContacts._ID, rawContactId);
3496a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
3497a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        // Check that querying for the profile gets the created raw contact.
3498a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro        assertStoredValues(Profile.CONTENT_RAW_CONTACTS_URI, values);
3499a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro    }
3500a09d7527b132ec82f98cde1564b0262fd85768c2Dave Santoro
350185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfilePhoto() throws IOException {
350285077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
350385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
350487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
350585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.THUMBNAIL),
350685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, false));
350785077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
350885077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
350985077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    public void testLoadProfileDisplayPhoto() throws IOException {
351085077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        long rawContactId = createBasicProfileContact(new ContentValues());
351185077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
351287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
351385077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
351485077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro                Contacts.openContactPhotoInputStream(mResolver, Profile.CONTENT_URI, true));
351585077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro    }
351685077339f2e0c6f21fd92fb8df335f3aae004fbaDave Santoro
35170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testPhonesWithStatusUpdate() {
351819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
351919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        ContentValues values = new ContentValues();
352019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
352119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
35228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
352319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
352419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
352519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664411");
352619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertPhoneNumber(rawContactId, "18004664412");
352719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog411@acme.com");
352819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        insertEmail(rawContactId, "goog412@acme.com");
352919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
353082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
3531aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.INVISIBLE, "Bad",
3532aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
353382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog412@acme.com",
3534aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, "Good",
3535aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VOICE);
353619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
353719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
353882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri uri = Data.CONTENT_URI;
353919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
3540a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        Cursor c = mResolver.query(uri, null, RawContacts.CONTACT_ID + "=" + contactId + " AND "
3541a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov                + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'", null, Phone.NUMBER);
354219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertEquals(2, c.getCount());
354319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
354419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToFirst();
354519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
354619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
354782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
35480a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
354919a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
355019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664411");
355119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
3552a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
355319a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
355419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
355519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.moveToNext();
355619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
355719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.clear();
355882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
35590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Bad");
356019a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "John Doe");
356119a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.put(Phone.NUMBER, "18004664412");
356219a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        values.putNull(Phone.LABEL);
3563a6def2055f5d12cb6ee5cc3dc1adaf39f2b7c97cDmitri Plotnikov        values.put(RawContacts.CONTACT_ID, contactId);
356419a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        assertCursorValues(c, values);
356519a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
356619a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov        c.close();
356719a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov    }
356819a0962e62c13a5e5f8e5b4eed5e30d3477894b4Dmitri Plotnikov
356989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testGroupQuery() {
357089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
357189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
357289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId1 = createGroup(account1, "e", "f");
357389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        long groupId2 = createGroup(account2, "g", "h");
35748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account1);
35758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Groups.CONTENT_URI, account2);
357689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
357789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
357889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Groups._ID + "=" + groupId1, null, Groups._ID, groupId1) ;
357989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Groups._ID + "=" + groupId2, null, Groups._ID, groupId2) ;
358089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
358189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
35823cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    public void testGroupInsert() {
35833cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        ContentValues values = new ContentValues();
35843cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
35853cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_NAME, "a");
35863cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.ACCOUNT_TYPE, "b");
35879d990d339c9e3a9e03f6fe13c260d36665f00e61Makoto Onuki        values.put(Groups.DATA_SET, "ds");
35883cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SOURCE_ID, "c");
35893cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.VERSION, 42);
35903cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.GROUP_VISIBLE, 1);
35913cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE, "d");
35923cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.TITLE_RES, 1234);
35933cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.NOTES, "e");
35943cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.RES_PACKAGE, "f");
35953cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYSTEM_ID, "g");
359694021b213e4db367f60b30fcbfe9019e28571784Fred Quintana        values.put(Groups.DELETED, 1);
35973cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC1, "h");
35983cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC2, "i");
35993cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC3, "j");
36003cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        values.put(Groups.SYNC4, "k");
36013cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
36023cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        Uri rowUri = mResolver.insert(Groups.CONTENT_URI, values);
36033cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
360473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(Groups.DIRTY, 1);
36053cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertStoredValues(rowUri, values);
36063cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov    }
36073cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov
3608f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupCreationAfterMembershipInsert() {
36098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3610f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3611f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3612f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId = assertSingleGroup(NO_LONG, mAccount, "gsid1", null);
3613f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3614f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId, "gsid1");
3615f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3616f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3617f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupReuseAfterMembershipInsert() {
36188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3619f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3620f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        Uri groupMembershipUri = insertGroupMembership(rawContactId1, "gsid1");
3621f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3622f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroup(groupId1, mAccount, "gsid1", "title1");
3623f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertSingleGroupMembership(ContentUris.parseId(groupMembershipUri),
3624f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa                rawContactId1, groupId1, "gsid1");
3625f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3626f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3627f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupInsertFailureOnGroupIdConflict() {
36288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
3629f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        long groupId1 = createGroup(mAccount, "gsid1", "title1");
3630f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3631f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues values = new ContentValues();
3632f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.RAW_CONTACT_ID, rawContactId1);
3633f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
3634f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_SOURCE_ID, "gsid1");
3635f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        values.put(GroupMembership.GROUP_ROW_ID, groupId1);
3636f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        try {
3637f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            mResolver.insert(Data.CONTENT_URI, values);
3638f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            fail("the insert was expected to fail, but it succeeded");
3639f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        } catch (IllegalArgumentException e) {
3640f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa            // this was expected
3641f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        }
3642f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3643f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
36445f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountSelection() {
36455f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
36465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
36475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
36495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
36505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
36515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(Groups.CONTENT_URI,
36535f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=?",
36545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[]{account2.name, account2.type});
36555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
36565f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36575f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
36585f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
36595f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
36605f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36615f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
36625f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
36635f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
36645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
36665f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
36675f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
36685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36695f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
36705f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
36715f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36725f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testGroupDelete_byAccountParam() {
36735f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account1 = new Account("accountName1", "accountType1");
36745f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final Account account2 = new Account("accountName2", "accountType2");
36755f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36765f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId1 = createGroup(account1, "sourceId1", "title1");
36775f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId2 = createGroup(account2, "sourceId2", "title2");
36785f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final long groupId3 = createGroup(account2, "sourceId3", "title3");
36795f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36805f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        final int numDeleted = mResolver.delete(
36815f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                Groups.CONTENT_URI.buildUpon()
36825f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_NAME, account2.name)
36835f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .appendQueryParameter(Groups.ACCOUNT_TYPE, account2.type)
36845f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                    .build(),
36855f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                null, null);
36865f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(2, numDeleted);
36875f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36885f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v1 = new ContentValues();
36895f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups._ID, groupId1);
36905f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v1.put(Groups.DELETED, 0);
36915f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36925f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v2 = new ContentValues();
36935f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups._ID, groupId2);
36945f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v2.put(Groups.DELETED, 1);
36955f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
36965f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        ContentValues v3 = new ContentValues();
36975f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups._ID, groupId3);
36985f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        v3.put(Groups.DELETED, 1);
36995f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
37005f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValues(Groups.CONTENT_URI, new ContentValues[] { v1, v2, v3 });
37015f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
37025f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
3703f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    public void testGroupSummaryQuery() {
3704f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account1 = new Account("accountName1", "accountType1");
3705f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final Account account2 = new Account("accountName2", "accountType2");
3706f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId1 = createGroup(account1, "sourceId1", "title1");
3707f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId2 = createGroup(account2, "sourceId2", "title2");
3708f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId3 = createGroup(account2, "sourceId3", "title3");
3709f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3710f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Prepare raw contact id not used at all, to test group summary uri won't be confused
3711f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // with it.
37128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId0 = RawContactUtil.createRawContactWithName(mResolver, "firstName0",
37138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName0");
3714f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
37158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "firstName1",
37168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName1");
3717f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId1, "address1@email.com");
3718f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId1, groupId1);
3719f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
37208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "firstName2",
37218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName2");
3722f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId2, "address2@email.com");
3723f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId2, "222-222-2222");
3724f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId2, groupId1);
3725f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3726f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v1 = new ContentValues();
3727f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups._ID, groupId1);
3728f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.TITLE, "title1");
3729f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SOURCE_ID, "sourceId1");
3730f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_NAME, account1.name);
3731f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.ACCOUNT_TYPE, account1.type);
3732f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_COUNT, 2);
3733f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, 1);
3734f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3735f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v2 = new ContentValues();
3736f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups._ID, groupId2);
3737f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.TITLE, "title2");
3738f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SOURCE_ID, "sourceId2");
3739f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_NAME, account2.name);
3740f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.ACCOUNT_TYPE, account2.type);
3741f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, 0);
3742f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, 0);
3743f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3744f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v3 = new ContentValues();
3745f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups._ID, groupId3);
3746f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.TITLE, "title3");
3747f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SOURCE_ID, "sourceId3");
3748f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_NAME, account2.name);
3749f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.ACCOUNT_TYPE, account2.type);
3750f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_COUNT, 0);
3751f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v3.put(Groups.SUMMARY_WITH_PHONES, 0);
3752f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3753f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3754f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3755f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Now rawContactId1 has two phone numbers.
3756f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1111");
3757f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId1, "111-111-1112");
3758f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Result should reflect it correctly (don't count phone numbers but raw contacts)
3759f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v1.put(Groups.SUMMARY_WITH_PHONES, v1.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3760f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3761f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3762f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce new raw contact, pretending the user added another info.
37638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "firstName3",
37648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "lastName3");
3765f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertEmail(rawContactId3, "address3@email.com");
3766f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertPhoneNumber(rawContactId3, "333-333-3333");
3767f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        insertGroupMembership(rawContactId3, groupId2);
3768f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_COUNT, v2.getAsInteger(Groups.SUMMARY_COUNT) + 1);
3769f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v2.put(Groups.SUMMARY_WITH_PHONES, v2.getAsInteger(Groups.SUMMARY_WITH_PHONES) + 1);
3770f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3771f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(Groups.CONTENT_SUMMARY_URI, new ContentValues[] { v1, v2, v3 });
3772f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
377318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        final Uri uri = Groups.CONTENT_SUMMARY_URI;
377418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki
377518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        // TODO Once SUMMARY_GROUP_COUNT_PER_ACCOUNT is supported remove all the if(false).
377618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
377718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 1);
377818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
377918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 2);
378018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
378118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
378218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v2.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
378318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v3.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
378418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3785f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3 });
3786f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
3787f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // Introduce another group in account1, testing SUMMARY_GROUP_COUNT_PER_ACCOUNT correctly
3788f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        // reflects the change.
3789f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        final long groupId4 = createGroup(account1, "sourceId4", "title4");
379018b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
379118b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
379218b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT) + 1);
379318b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
379418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v1.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
379518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3796f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        ContentValues v4 = new ContentValues();
3797f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups._ID, groupId4);
3798f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.TITLE, "title4");
3799f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SOURCE_ID, "sourceId4");
3800f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_NAME, account1.name);
3801f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.ACCOUNT_TYPE, account1.type);
3802f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_COUNT, 0);
3803f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        v4.put(Groups.SUMMARY_WITH_PHONES, 0);
380418b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        if (false) {
380518b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT,
380618b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki                    v1.getAsInteger(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT));
380718b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        } else {
380818b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki            v4.put(Groups.SUMMARY_GROUP_COUNT_PER_ACCOUNT, 0);
380918b09495f5f37b38ff2e1c965e087dfde68c27fbMakoto Onuki        }
3810f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa        assertStoredValues(uri, new ContentValues[] { v1, v2, v3, v4 });
381123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki
381223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // We change the tables dynamically according to the requested projection.
381323ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        // Make sure the SUMMARY_COUNT column exists
381423ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.clear();
381523ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v1.put(Groups.SUMMARY_COUNT, 2);
381623ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.clear();
381723ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v2.put(Groups.SUMMARY_COUNT, 1);
381823ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.clear();
381923ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v3.put(Groups.SUMMARY_COUNT, 0);
382023ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.clear();
382123ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        v4.put(Groups.SUMMARY_COUNT, 0);
382223ba865a6d204ba4aa29d2fad9989e9c44351e81Makoto Onuki        assertStoredValuesWithProjection(uri, new ContentValues[] { v1, v2, v3, v4 });
3823f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa    }
3824f1efadb1255fd75305b59802f736905b9d66e449Daisuke Miyakawa
382589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testSettingsQuery() {
382689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
382789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
3828f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account3 = new AccountWithDataSet("e", "f", "plus");
382989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account1, "0", "0");
383089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        createSettings(account2, "1", "1");
3831f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account3, "1", "0");
38328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account1);
38338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(Settings.CONTENT_URI, account2);
3834f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Uri uri3 = Settings.CONTENT_URI.buildUpon()
3835f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_NAME, account3.getAccountName())
3836f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account3.getAccountType())
3837f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .appendQueryParameter(RawContacts.DATA_SET, account3.getDataSet())
3838f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro                .build();
383989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
384089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
3841f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertEquals(1, getCount(uri3, null, null));
384289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, Settings.SHOULD_SYNC, "0") ;
3843f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri1, Settings.UNGROUPED_VISIBLE, "0");
384489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, Settings.SHOULD_SYNC, "1") ;
3845f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri2, Settings.UNGROUPED_VISIBLE, "1");
3846f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.SHOULD_SYNC, "1");
3847f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        assertStoredValue(uri3, Settings.UNGROUPED_VISIBLE, "0");
3848f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    }
3849f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
3850f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro    public void testSettingsInsertionPreventsDuplicates() {
3851f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        Account account1 = new Account("a", "b");
3852f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        AccountWithDataSet account2 = new AccountWithDataSet("c", "d", "plus");
3853f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account1, "0", "0");
3854f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro        createSettings(account2, "1", "1");
3855f9b77edaf5855bf6932fbc4b4b4342273669efefDave Santoro
38560e21a867a572679d64d79041eb574d13665178d4Dave Santoro        // Now try creating the settings rows again.  It should update the existing settings rows.
38570e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account1, "1", "0");
38580e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
38590e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=?",
38600e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"a", "b"}, Settings.SHOULD_SYNC, "1");
38610e21a867a572679d64d79041eb574d13665178d4Dave Santoro
38620e21a867a572679d64d79041eb574d13665178d4Dave Santoro        createSettings(account2, "0", "1");
38630e21a867a572679d64d79041eb574d13665178d4Dave Santoro        assertStoredValue(Settings.CONTENT_URI,
38640e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.ACCOUNT_NAME + "=? AND " + Settings.ACCOUNT_TYPE + "=? AND " +
38650e21a867a572679d64d79041eb574d13665178d4Dave Santoro                Settings.DATA_SET + "=?",
38660e21a867a572679d64d79041eb574d13665178d4Dave Santoro                new String[] {"c", "d", "plus"}, Settings.SHOULD_SYNC, "0");
386789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
386889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
38694097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsUnspecified() {
38708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38714097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
38724097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
38738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
38744097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
387517a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
38764097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
38774097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
387867c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    public void testDisplayNameParsingWhenPartsAreNull() {
38798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
388067c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        ContentValues values = new ContentValues();
388167c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
388267c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
388367c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
38848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
388517a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        assertStructuredName(rawContactId, "Mr.", "John", "Kevin", "von Smith", "Jr.");
388667c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov    }
388767c9ed1cefa5c084d3f373d7f1ecb7122983ff15Dmitri Plotnikov
38884097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    public void testDisplayNameParsingWhenPartsSpecified() {
38898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
38904097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        ContentValues values = new ContentValues();
38914097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr.John Kevin von Smith, Jr.");
38924097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Johnson");
38938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
38944097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
38955ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertStructuredName(rawContactId, null, null, null, "Johnson", null);
38964097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov    }
38974097855e2d672b3f8e1c5c8a169efb80203bf53eDmitri Plotnikov
38985dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithoutPhoneticName() {
3899a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.ENGLISH);
39008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, null);
39015dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39025dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
39035dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
39045dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
39055dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "K.");
39065dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
39075dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
39088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
39095dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
39115dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
391255e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
391355e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
39145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
39155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
39165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3917a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
39185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3919a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
39205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
39225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
39235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
39255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
392655e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "Mr John K. Doe, Jr.");
392755e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "Mr Doe, John K., Jr.");
39285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
39295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
39305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "John K. Doe, Jr.");
3931a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "J");
39325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Doe, John K., Jr.");
3933a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
39345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
39365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
39375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
39385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
39405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
39415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
39425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithChineseName() {
3944a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
39455dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov            return;
39465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        }
3947a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
39485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
39505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
3952a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        // "DUAN \u6BB5 XIAO \u5C0F TAO \u6D9B"
39535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "\u6BB5\u5C0F\u6D9B");
39548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
39555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
39575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
39585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
39595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
39605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(RawContacts.PHONETIC_NAME);
39615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3962a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3963a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3964a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3965a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
39665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39675dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
39685dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
39695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
39715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
39725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u6BB5\u5C0F\u6D9B");
39735dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
39745dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
39755dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
3976a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u6BB5\u5C0F\u6D9B");
3977a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "D");
3978a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u6BB5\u5C0F\u6D9B");
3979a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "D");
39805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
39825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
39835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
39845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
39865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
39875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
39885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
39890f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    public void testJapaneseNameContactInEnglishLocale() {
39900f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // Need Japanese locale data for transliteration
39910f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        if (!hasJapaneseCollator()) {
39920f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner            return;
39930f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        }
39940f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContactLocaleUtils.setLocale(Locale.US);
3995ef5fa9a68690d19e2a9c9748d63e2cabb5075813Jay Shrauner        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
39960f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
39970f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        ContentValues values = new ContentValues();
39980f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
39990f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
40009aec6b8422f8d153a91a241f1b10d6e48d338bb8Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
40010f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
40020f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
40030f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // en_US should behave same as ja_JP (match on Hiragana and Romaji
40040f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // but not Pinyin)
40050f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
40060f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
40070f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
40080f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner    }
40090f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
40105dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testContactWithJapaneseName() {
4011a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
4012a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
4013a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
4014a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
40158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, null);
40165dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
40185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "\u7A7A\u6D77");
40195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(StructuredName.PHONETIC_GIVEN_NAME, "\u304B\u3044\u304F\u3046");
40208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri dataUri = DataUtil.insertStructuredName(mResolver, rawContactId, values);
40215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
40235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
40245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
40255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
40265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
40275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
40285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
40295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(RawContacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
4030a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
4031a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(RawContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
40325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
40345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(rawContactUri, values);
40355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
40375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_SOURCE, DisplayNameSources.STRUCTURED_NAME);
40385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_PRIMARY, "\u7A7A\u6D77");
40395dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME_ALTERNATIVE, "\u7A7A\u6D77");
40405dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u304B\u3044\u304F\u3046");
40415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
40425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u304B\u3044\u304F\u3046");
40435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u304B\u3044\u304F\u3046");
4044a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u304B");
4045a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u304B");
40465dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40475dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
40485dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov                queryContactId(rawContactId));
40495dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(contactUri, values);
40505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
40515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // The same values should be available through a join with Data
40525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(dataUri, values);
40530f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner
40540f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        long contactId = queryContactId(rawContactId);
40550f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        // ja_JP should match on Hiragana and Romaji but not Pinyin
40560f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "\u304B\u3044\u304F\u3046");
40570f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilter(contactId, "kaiku");
40580f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertContactFilterNoResult("kong");
40595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
40605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
406125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    public void testDisplayNameUpdate() {
40628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
406325abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertEmail(rawContactId1, "potato@acme.com", true);
406425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
40658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
406625abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        insertPhoneNumber(rawContactId2, "123456789", true);
406725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
40680c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
40690c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
407025abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
407125abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "123456789");
407225abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
40738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Potato", "Head");
407425abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
407525abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2, "Potato Head");
407681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
407725abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov    }
407825abcf949c0dd826a770b437489b83de48975ceaDmitri Plotnikov
407901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    public void testDisplayNameFromData() {
40808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
408101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4082a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        ContentValues values = new ContentValues();
408301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
408401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
408501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
408601911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
408701911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "mike@monstersinc.com");
408801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "mike@monstersinc.com");
408901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
409001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertEmail(rawContactId, "james@monstersinc.com", true);
409101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "james@monstersinc.com");
409201911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
409301911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        insertPhoneNumber(rawContactId, "1-800-466-4411");
409401911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "1-800-466-4411");
409501911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
4096a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there are title and company, the company is display name.
4097a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
4098a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(Organization.COMPANY, "Monsters Inc");
40995dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
410001911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Monsters Inc");
410101911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
4102a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is nickname, that is display name.
4103a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        insertNickname(rawContactId, "Sully");
4104a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Sully");
4105a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka
4106a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        // If there is structured name, that is display name.
4107a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.clear();
4108a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.GIVEN_NAME, "James");
4109a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.MIDDLE_NAME, "P.");
4110a5d05d90333a70d471d78e82caeb5cfa2e4d4c59Tadashi G. Takaoka        values.put(StructuredName.FAMILY_NAME, "Sullivan");
41118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, values);
41125dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "James P. Sullivan");
41135dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
41145dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41155dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithoutPhoneticName() {
41168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
41175dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
41185dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
41195dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41205dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
41215dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41225dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
41235dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41245dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.TITLE, "Protagonist");
41255dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
41265dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Protagonist");
41275dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41285dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there are title and company, the company is display name.
41295dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41305dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "Monsters Inc");
41315dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
41325dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41335dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41345dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "Monsters Inc");
41355dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
41365dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
41375dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "Monsters Inc");
41385dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "Monsters Inc");
4139a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "M");
4140a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "M");
41415dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
41425dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
41435dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41445dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithJapanesePhoneticName() {
4145a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasJapaneseCollator()) {
4146a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            return;
4147a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
4148a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.JAPAN);
41498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
41505dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
41515dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
41525dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41535dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
41545dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41555dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
41565dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41575dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "DoCoMo");
41585dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
41595dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
41605dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41615dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41625dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "DoCoMo");
41635dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME, "\u30C9\u30B3\u30E2");
41645dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.JAPANESE);
41655dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_PRIMARY, "\u30C9\u30B3\u30E2");
41665dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u30C9\u30B3\u30E2");
4167a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "\u305F");
4168a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "\u305F");
41695dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
41705dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    }
41715dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41725dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov    public void testDisplayNameFromOrganizationWithChineseName() {
4173a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        if (!hasChineseCollator()) {
41740b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov            return;
41750b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov        }
4176a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        ContactLocaleUtils.setLocale(Locale.SIMPLIFIED_CHINESE);
41770b1eaf562411ffec26fd9113c3209ebdd29202e1Dmitri Plotnikov
41788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
41795dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
41805dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        ContentValues values = new ContentValues();
41815dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41825dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
41835dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41845dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        // If there is title without company, the title is display name.
41855dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41865dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Organization.COMPANY, "\u4E2D\u56FD\u7535\u4FE1");
41875dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
41885dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov
41895dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.clear();
41905dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.DISPLAY_NAME, "\u4E2D\u56FD\u7535\u4FE1");
41915dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.putNull(Contacts.PHONETIC_NAME);
41925dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        values.put(Contacts.PHONETIC_NAME_STYLE, PhoneticNameStyle.UNDEFINED);
4193a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_PRIMARY, "\u4E2D\u56FD\u7535\u4FE1");
4194a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_PRIMARY, "Z");
4195a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(Contacts.SORT_KEY_ALTERNATIVE, "\u4E2D\u56FD\u7535\u4FE1");
4196a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        values.put(ContactsColumns.PHONEBOOK_LABEL_ALTERNATIVE, "Z");
41975dd6d5d4acb93adc05f1fde904080787f2397f51Dmitri Plotnikov        assertStoredValues(uri, values);
419801911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov    }
419901911fa9cfa21f198fd767eedde072acbb879f28Dmitri Plotnikov
420031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    public void testLookupByOrganization() {
42018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
420231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        long contactId = queryContactId(rawContactId);
420331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        ContentValues values = new ContentValues();
420431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
420531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
420631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
420731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "president");
420831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
420931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
421031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
421131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
421231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
421331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
421431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.DEPARTMENT, "software");
421531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
421631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
421731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "acmecorp");
421831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
421931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
422031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
422131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "incredibles");
422231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
422331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
422431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
422531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "president");
422631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
422731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
422831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "director");
422931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
423031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
423131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "incredibles");
423231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "director");
423331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
423431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.clear();
423531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.COMPANY, "monsters");
423631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        values.put(Organization.TITLE, "scarer");
423731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        mResolver.update(organizationUri, values, null, null);
423831168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
423931168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "monsters");
424031168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertContactFilter(contactId, "scarer");
424131168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
424231168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
424331168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    private void assertContactFilter(long contactId, String filter) {
424431168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
424531168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov        assertStoredValue(filterUri, Contacts._ID, contactId);
424631168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov    }
424731168f49a3da9b9a9d5346f3d6a8098b76179c9cDmitri Plotnikov
4248a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    private void assertContactFilterNoResult(String filter) {
42490f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        Uri filterUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(filter));
42500f4b7a9bfe4b2079a7c5bb22b4114b5672639b05Jay Shrauner        assertEquals(0, getCount(filterUri, null, null));
4251a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov    }
4252a1e177389debb74a51587720464a527a193bffc1Dmitri Plotnikov
4253916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetOrganization() throws Exception {
42548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
4255916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4256916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4257916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Some random data element
4258916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "inc@corp.com");
4259916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4260916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
4261916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
4262916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmecorp");
42639c6ef008d92017108e3d10dcd8e2146eded9e148Dmitri Plotnikov        values.put(Organization.TITLE, "engineer");
4264916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri organizationUri = insertOrganization(rawContactId, values);
4265916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4266916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another matching organization
4267916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "acmeinc");
4268916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
4269916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4270916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // Add another non-matching organization
4271916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Organization.COMPANY, "corpacme");
4272916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertOrganization(rawContactId, values);
4273916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4274916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        // And another data element
4275916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        insertEmail(rawContactId, "emca@corp.com", true, Email.TYPE_CUSTOM, "Custom");
4276916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
42776f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
4278916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4279916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
4280916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
428154b97025256764a01f927792e64de8bf369e12f1Yorke Lee        values.put(SearchSnippets.SNIPPET, "acmecorp");
42826fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(filterUri, values);
4283916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
4284916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4285916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetEmail() throws Exception {
42868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4287916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4288916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
4289916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
42908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
4291916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertEmail(rawContactId, "acme@corp.com", true, Email.TYPE_CUSTOM, "Custom");
4292916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
42936f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("acme", true);
4294916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4295916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
4296916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
429754b97025256764a01f927792e64de8bf369e12f1Yorke Lee        values.put(SearchSnippets.SNIPPET, "acme@corp.com");
4298916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
4299916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
4300916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4301fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    public void testCountPhoneNumberDigits() {
4302fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("86 (0) 5-55-12-34"));
4303fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("860 555-1234"));
4304fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(3, ContactsProvider2.countPhoneNumberDigits("860"));
4305fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(10, ContactsProvider2.countPhoneNumberDigits("8605551234"));
4306fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860555"));
4307fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860 555"));
4308fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(6, ContactsProvider2.countPhoneNumberDigits("860-555"));
4309fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(12, ContactsProvider2.countPhoneNumberDigits("+441234098765"));
4310fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("44+1234098765"));
4311fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood        assertEquals(0, ContactsProvider2.countPhoneNumberDigits("+441234098foo"));
4312fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood    }
4313fa5cdd337d4d696d326db03c68bfae8645c83b14Mathew Inwood
43143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetPhone() throws Exception {
43158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
43173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues values = new ContentValues();
43183716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
43203716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "(860) 555-1234");
43213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.clear();
43233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        values.put(Contacts._ID, contactId);
432454b97025256764a01f927792e64de8bf369e12f1Yorke Lee        values.put(SearchSnippets.SNIPPET, "[(860) 555-1234]");
43253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("86 (0) 5-55-12-34")), values);
43283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43293716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555-1234")), values);
43303716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860")), values);
43323716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("8605551234")), values);
43343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43353716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860555")), values);
43363716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43373716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860 555")), values);
43383716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        assertStoredValues(Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
43393716f1447ceb21180d1301790eabd8b9453f486dDave Santoro                Uri.encode("860-555")), values);
43403716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
43413716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43426f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    private Uri buildFilterUri(String query, boolean deferredSnippeting) {
43436f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri.Builder builder = Contacts.CONTENT_FILTER_URI.buildUpon()
43446f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro                .appendPath(Uri.encode(query));
43456f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        if (deferredSnippeting) {
43466f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro            builder.appendQueryParameter(ContactsContract.DEFERRED_SNIPPETING, "1");
43476f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        }
43486f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        return builder.build();
43496f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro    }
43506f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro
43516fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    public ContentValues createSnippetContentValues(long contactId, String snippet) {
43526fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        final ContentValues values = new ContentValues();
43536fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.clear();
43546fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        values.put(Contacts._ID, contactId);
435554b97025256764a01f927792e64de8bf369e12f1Yorke Lee        values.put(SearchSnippets.SNIPPET, snippet);
43566fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        return values;
43576fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng    }
43586fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng
4359916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    public void testSearchSnippetNickname() throws Exception {
43608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
4361916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4362916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        ContentValues values = new ContentValues();
4363916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4364916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        Uri dataUri = insertNickname(rawContactId, "Incredible");
4365916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
43666f983fd835f0cdd5ac7931ccd49d44e9ea4c87c0Dave Santoro        Uri filterUri = buildFilterUri("inc", true);
4367916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
4368916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.clear();
4369916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        values.put(Contacts._ID, contactId);
437054b97025256764a01f927792e64de8bf369e12f1Yorke Lee        values.put(SearchSnippets.SNIPPET, "Incredible");
4371916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov        assertStoredValues(filterUri, values);
4372916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov    }
4373916f2d7104bfba857412a66b40ed60fea6546222Dmitri Plotnikov
43743716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNameInDisplayName() throws Exception {
43758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43763716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
43778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "Cave", "Johnson");
43783716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
43793716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43806fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
43813716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43826fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
43836fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("john", true), snippet);
43843716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
43853716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43863716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForNicknameInDisplayName() throws Exception {
43878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43883716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
43893716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNickname(rawContactId, "Caveman");
43903716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
43913716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43926fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "cave@aperturescience.com");
43933716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43946fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
43953716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
43963716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
43973716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForCompanyInDisplayName() throws Exception {
43988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
43993716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
44003716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        ContentValues company = new ContentValues();
44013716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.clear();
44023716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.COMPANY, "Aperture Science");
44033716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        company.put(Organization.TITLE, "President");
44043716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertOrganization(rawContactId, company);
44053716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "aperturepresident@aperturescience.com", true);
44063716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44076fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "aperturepresident");
44083716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44096fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("aperture", true), snippet);
44103716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
44113716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44123716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForPhoneInDisplayName() throws Exception {
44138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44143716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
44153716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertPhoneNumber(rawContactId, "860-555-1234");
44163716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "860@aperturescience.com", true);
44173716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44186fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId, "860-555-1234");
44193716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44206fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("860", true), snippet);
44213716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
44223716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44233716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    public void testSearchSnippetEmptyForEmailInDisplayName() throws Exception {
44248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44253716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        long contactId = queryContactId(rawContactId);
44263716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertEmail(rawContactId, "cave@aperturescience.com", true);
44273716f1447ceb21180d1301790eabd8b9453f486dDave Santoro        insertNote(rawContactId, "Cave Johnson is president of Aperture Science");
44283716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44296fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        ContentValues snippet = createSnippetContentValues(contactId,
44306fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng                "Cave Johnson is president of Aperture Science");
44313716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
44326fc2ed06c50b135caf4be3a212f2f82d48892c3fChiao Cheng        assertContainsValues(buildFilterUri("cave", true), snippet);
44333716f1447ceb21180d1301790eabd8b9453f486dDave Santoro    }
44343716f1447ceb21180d1301790eabd8b9453f486dDave Santoro
4435dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    public void testDisplayNameUpdateFromStructuredNameUpdate() {
44368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
44378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri nameUri = DataUtil.insertStructuredName(mResolver, rawContactId, "Slinky", "Dog");
4438dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4439dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4440dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4441dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4442dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky Dog");
4443dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4444dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        ContentValues values = new ContentValues();
4445dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.FAMILY_NAME);
4446dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4447dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
4448dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Slinky");
4449dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4450dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.putNull(StructuredName.GIVEN_NAME);
4451dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4452dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
4453dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, null);
4454dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4455dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dog");
4456dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        mResolver.update(nameUri, values, null, null);
4457dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4458dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "Dog");
4459dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov    }
4460dd0e0f44fe403ff201d46d5534f7f1148e5ad729Dmitri Plotnikov
4461d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    public void testInsertDataWithContentProviderOperations() throws Exception {
4462d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo1 = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
4463d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValues(new ContentValues())
4464d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
4465d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderOperation cpo2 = ContentProviderOperation.newInsert(Data.CONTENT_URI)
4466d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValueBackReference(Data.RAW_CONTACT_ID, 0)
4467d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
4468d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.GIVEN_NAME, "John")
4469d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .withValue(StructuredName.FAMILY_NAME, "Doe")
4470d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                .build();
4471d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        ContentProviderResult[] results =
4472d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov                mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(cpo1, cpo2));
4473d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        long contactId = queryContactId(ContentUris.parseId(results[0].uri));
4474d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4475d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov        assertStoredValue(uri, Contacts.DISPLAY_NAME, "John Doe");
4476d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov    }
4477d0f63551e3147babcebde5326b31285d7bdf6739Dmitri Plotnikov
4478d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailDefault() {
44798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
4480d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4481d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4482d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
4483d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
4484d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
4485d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(0, sendToVoicemail);
4486d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
4487d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4488d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4489d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtone() {
44908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
4491d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4492d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4493d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId, true, "foo");
4494d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, true, "foo");
449581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
44968c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
44978c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        updateSendToVoicemailAndRingtoneWithSelection(contactId, false, "bar");
44988c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId, false, "bar");
44998c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertNetworkNotified(false);
4500d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4501d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4502d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSendToVoicemailAndRingtoneAfterAggregation() {
45038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "a", "b");
4504d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
4505d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
4506d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
45078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "c", "d");
4508d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
4509d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, true, "bar");
4510d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4511d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
45120c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
45130c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4514d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4515d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        // Both contacts had "send to VM", the contact now has the same value
4516d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(contactId1, true, "foo,bar"); // Either foo or bar
4517d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4518d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4519d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testDoNotSendToVoicemailAfterAggregation() {
45208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "e", "f");
4521d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
4522d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, null);
4523d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
45248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "g", "h");
4525d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
4526d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, null);
4527d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4528d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
45290c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
45300c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4531d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4532d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Since one of the contacts had "don't send to VM" that setting wins for the aggregate
45330c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), false, null);
4534d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4535d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4536d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    public void testSetSendToVoicemailAndRingtonePreservedAfterJoinAndSplit() {
45378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "i", "j");
4538d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId1 = queryContactId(rawContactId1);
4539d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId1, true, "foo");
4540d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
45418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "k", "l");
4542d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        long contactId2 = queryContactId(rawContactId2);
4543d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        updateSendToVoicemailAndRingtone(contactId2, false, "bar");
4544d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4545d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Aggregate them
45460c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
45470c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4548d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
4549d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        // Split them
45500c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
45510c0adda32be5de3acf392ab715cff468b6b340f8Dmitri Plotnikov                rawContactId1, rawContactId2);
4552d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
45533cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId1), true, "foo");
4554d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        assertSendToVoicemailAndRingtone(queryContactId(rawContactId2), false, "bar");
4555d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
4556d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
455782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateInsert() {
45588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
45590a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
45600a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
45610a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45620a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
45630a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
45640a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
45650a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.putNull(StatusUpdates.CUSTOM_PROTOCOL);
45660a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
45670a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PRESENCE, StatusUpdates.INVISIBLE);
45680a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
45690a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 100);
45700a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "a.b.c");
45710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 1234);
45720a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 2345);
45730a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45740a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
45750a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45760a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
45770a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45780a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long contactId = queryContactId(rawContactId);
45790a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
45800a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45810a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
45820a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
45830a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Hiding");
45840a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
45850a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "a.b.c");
45860a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 1234);
45870a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 2345);
45880a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45890a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
45900a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
45910a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
45920a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
45930a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Cloaked");
45940a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_TIMESTAMP, 200);
45950a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_RES_PACKAGE, "d.e.f");
45960a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_ICON, 4321);
45970a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, 5432);
45980a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        mResolver.insert(StatusUpdates.CONTENT_URI, values);
45990a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46000a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
46010a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.INVISIBLE);
46020a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Cloaked");
46030a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 200);
46040a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_RES_PACKAGE, "d.e.f");
46050a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_ICON, 4321);
46060a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_LABEL, 5432);
46070a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(contactUri, values);
46080a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
46090a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46100a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateInferAttribution() {
46118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46120a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri imUri = insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
46130a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        long dataId = ContentUris.parseId(imUri);
46140a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46150a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        ContentValues values = new ContentValues();
46160a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
46170a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, Im.PROTOCOL_AIM);
46180a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.IM_HANDLE, "aim");
46190a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
46200a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46210a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        Uri resultUri = mResolver.insert(StatusUpdates.CONTENT_URI, values);
46220a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46230a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.clear();
46240a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.DATA_ID, dataId);
46250a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS_LABEL, com.android.internal.R.string.imProtocolAim);
46260a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(StatusUpdates.STATUS, "Hiding");
46270a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46280a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        assertStoredValues(resultUri, values);
46290a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    }
46300a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov
46310a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov    public void testStatusUpdateMatchingImOrEmail() {
46328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
46334dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
46344dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im");
463582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertEmail(rawContactId, "m@acme.com");
46364dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
46374dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (standard)
4638aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4639aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
46404dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
46414dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on IM (custom)
4642aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_CUSTOM, "my_im_proto", "my_im", StatusUpdates.IDLE, "Idle",
4643d9b5910dcb5cf99c4e4a81a794d5e81e17e4992eDaniel Lehmann                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO);
46444dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
46454dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // Match on Email
4646aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "m@acme.com", StatusUpdates.AWAY, "Away",
4647aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_VOICE);
46484dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
46494dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        // No match
4650aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_ICQ, null, "12345", StatusUpdates.DO_NOT_DISTURB, "Go away",
4651aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
46524dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
465382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Cursor c = mResolver.query(StatusUpdates.CONTENT_URI, new String[] {
465482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                StatusUpdates.DATA_ID, StatusUpdates.PROTOCOL, StatusUpdates.CUSTOM_PROTOCOL,
46550a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov                StatusUpdates.PRESENCE, StatusUpdates.STATUS},
465682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                PresenceColumns.RAW_CONTACT_ID + "=" + rawContactId, null, StatusUpdates.DATA_ID);
46574dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
465882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_AIM, null, StatusUpdates.AVAILABLE, "Available");
46594dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
466082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_CUSTOM, "my_im_proto", StatusUpdates.IDLE, "Idle");
46614dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertTrue(c.moveToNext());
466282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertStatusUpdate(c, Im.PROTOCOL_GOOGLE_TALK, null, StatusUpdates.AWAY, "Away");
46634dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertFalse(c.moveToNext());
46644dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        c.close();
4665bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4666bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4667bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4668bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4669bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
467082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
46710a185cdcb65d1beb2a295fffbe2ae11a6a2c097fDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4672bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4673bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov    }
4674bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
467582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateUpdateAndDelete() {
46768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4677bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4678bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4679bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4680bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4681bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4682bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        ContentValues values = new ContentValues();
468382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
468482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_STATUS);
4685bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4686bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
4687aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AWAY, "BUSY",
4688aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
4689aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.DO_NOT_DISTURB, "GO AWAY",
4690aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
469182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        Uri statusUri =
4692aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4693aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                    StatusUpdates.CAPABILITY_HAS_CAMERA);
469482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4695bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
469682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
469782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4698bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4699bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov
47009705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for
47019705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status
47029705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     status_updates.status_ts
47039705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //     presence
47049705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        long updatedTs = 200;
47059705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String testUpdate = "test_update";
47069705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        String selection = StatusUpdates.DATA_ID + "=" + statusId;
47079705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
47089705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
47099705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
47109705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
47119705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
47129705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
47139705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
47149705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
47159705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in status_updates table ONLY
47169705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in presence table are to be updated.
47179705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        updatedTs = 300;
47189705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        testUpdate = "test_update_new";
47199705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
47209705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
47219705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
47229705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
47239705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
47249705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
47259705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the presence column value is still the old value
47269705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test");
47279705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
47289705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
47299705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // update status_updates table to set new values for columns in presence table ONLY
47309705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // i.e., no rows in status_updates table are to be updated.
47319705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        selection = StatusUpdates.DATA_ID + "=" + statusId;
47329705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
47339705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.PRESENCE, "presence_test_new");
47349705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        mResolver.update(StatusUpdates.CONTENT_URI, values,
47359705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori                StatusUpdates.DATA_ID + "=" + statusId, null);
47369705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // make sure the status_updates table is not updated
47379705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS_TIMESTAMP, updatedTs);
47389705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.put(StatusUpdates.STATUS, testUpdate);
47399705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        assertStoredValuesWithProjection(StatusUpdates.CONTENT_URI, values);
47409705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori
47419705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        // effect "delete status_updates" operation and expect the following
47429705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   data deleted from status_updates table
47439705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        //   presence set to null
474482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        mResolver.delete(StatusUpdates.CONTENT_URI, StatusUpdates.DATA_ID + "=" + statusId, null);
47459705f5bcb04c4b3012a762fb3ba8620b518587ccVasu Nori        values.clear();
474682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4747a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4748a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov    }
4749a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4750093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    public void testStatusUpdateUpdateToNull() {
47518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4752093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4753093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4754093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long contactId = queryContactId(rawContactId);
4755093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4756093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4757093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        ContentValues values = new ContentValues();
4758093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        Uri statusUri =
4759093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov            insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", StatusUpdates.AVAILABLE, "Available",
4760093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                    StatusUpdates.CAPABILITY_HAS_CAMERA);
4761093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        long statusId = ContentUris.parseId(statusUri);
4762093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4763093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_PRESENCE, StatusUpdates.AVAILABLE);
4764093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4765093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4766093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4767093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4768093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(StatusUpdates.PRESENCE);
4769093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        mResolver.update(StatusUpdates.CONTENT_URI, values,
4770093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov                StatusUpdates.DATA_ID + "=" + statusId, null);
4771093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
4772093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.clear();
4773093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.putNull(Contacts.CONTACT_PRESENCE);
4774093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4775093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
4776093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov    }
4777093b6446d0c63b8d725324ea41369b76ace153dfDmitri Plotnikov
477882bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testStatusUpdateWithTimestamp() {
47798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
4780a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_AIM, null, "aim");
4781a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "gtalk");
4782a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4783a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
4784a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
4785aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Offline", 80,
47865d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4787aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_AIM, null, "aim", 0, "Available", 100,
47885d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4789aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "gtalk", 0, "Busy", 90,
47905d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
4791a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov
4792a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        // Should return the latest status
4793a23cd5b6f478f6c9dda54173e84bd0098b9f3364Dmitri Plotnikov        ContentValues values = new ContentValues();
479482bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS_TIMESTAMP, 100);
479582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(Contacts.CONTACT_STATUS, "Available");
4796bffeabdf3dcf58f963ad1bb4d3e6e51f3ac16cfdDmitri Plotnikov        assertStoredValuesWithProjection(contactUri, values);
47974dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
47984dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
479982bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    private void assertStatusUpdate(Cursor c, int protocol, String customProtocol, int presence,
480082bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov            String status) {
48014dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        ContentValues values = new ContentValues();
480282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.PROTOCOL, protocol);
480382bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.CUSTOM_PROTOCOL, customProtocol);
4804a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov        values.put(StatusUpdates.PRESENCE, presence);
480582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        values.put(StatusUpdates.STATUS, status);
48064dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        assertCursorValues(c, values);
48074dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov    }
48084dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov
48093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item query test cases.
48103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByRawContactId() {
48128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
48133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
48143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, mAccount);
48153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
48163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
48173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
48183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
48193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
48203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByContactId() {
48238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
48253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
48263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
48273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
48283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
48293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
48303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
48313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
48323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKey() {
48358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
48373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
48383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
48393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
48403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
48413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
48423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
48433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
48443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
48453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsByLookupKeyAndContactId() {
48488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long contactId = queryContactId(rawContactId);
48503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        String lookupKey = queryLookupKey(contactId);
48513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
48523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
48533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(
48543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
48553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(
48563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI, lookupKey),
48573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                contactId),
48583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Contacts.StreamItems.CONTENT_DIRECTORY),
48593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                values);
48603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItems() {
48638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
48653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, values, null);
48663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, values);
48673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemsWithSelection() {
48708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
48723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
48733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
48753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
48763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
48773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
48793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
48803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"}, firstValues);
48813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
48833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
48843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Goodbye world"}, secondValues);
48853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
48863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemById() {
48888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
48893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
48903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
48913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
48923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
48943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
48953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
48963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
48973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
48983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first stream item.
48993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
49003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstValues);
49013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the second stream item.
49033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
49043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondValues);
49053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
49063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion + query test cases.
49083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoWithSelection() {
49108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
49113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
49123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
49133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
49143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
49163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo1Values, null);
49176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
49183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(2);
49193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, photo2Values, null);
49203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the first photo.
49223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_PHOTO_URI, StreamItemPhotos.SORT_INDEX + "=?",
49233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"1"}, photo1Values);
49243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
49253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemId() {
49278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
49283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
49303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
49313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
49323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
49333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
49353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
49363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
49373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
49383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
49403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
49413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
49426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
49433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
49453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
49466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
49476802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
49483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
49496802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
49503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select only the photos from the second stream item.
49523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
49533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
49543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY), photo2Values);
49553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
49563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemPhotoByStreamItemPhotoId() {
49588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
49593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a first stream item.
49613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
49623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
49633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
49643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert a second stream item.
49663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
49673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItem(rawContactId, secondValues, null);
49683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondStreamItemId = ContentUris.parseId(resultUri);
49693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the first stream item.
49713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo1Values = buildGenericStreamItemPhotoValues(1);
49723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(firstStreamItemId, photo1Values, null);
49733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstPhotoId = ContentUris.parseId(resultUri);
49746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo1Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
49753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Add a photo to the second stream item.
49773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photo2Values = buildGenericStreamItemPhotoValues(1);
49786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
49796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.galaxy, PhotoSize.ORIGINAL));
49803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(secondStreamItemId, photo2Values, null);
49813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long secondPhotoId = ContentUris.parseId(resultUri);
49826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photo2Values.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
49833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the first photo.
49853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
49863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
49873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
49883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
49893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                firstPhotoId),
49903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo1Values);
49913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
49923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Select the second photo.
49933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(ContentUris.withAppendedId(
49943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
49953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, secondStreamItemId),
49963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
49973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                secondPhotoId),
49983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                photo2Values);
49993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item insertion test cases.
50023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemInProfileRequiresWriteProfileAccess() {
50043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long profileRawContactId = createBasicProfileContact(new ContentValues());
50053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // With our (default) write profile permission, we should be able to insert a stream item.
50073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
50083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(profileRawContactId, values, null);
50093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now take away write profile permission.
50113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mActor.removePermissions("android.permission.WRITE_PROFILE");
50123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Try inserting another stream item.
50143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
50153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            insertStreamItem(profileRawContactId, values, null);
50163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            fail("Should require WRITE_PROFILE access to insert a stream item in the profile.");
50173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } catch (SecurityException expected) {
50183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // Trying to insert a stream item in the profile without WRITE_PROFILE permission
50193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            // should fail.
50203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
50213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemWithContentValues() {
50248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
50253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
50263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
50273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.insert(StreamItems.CONTENT_URI, values);
50283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
50293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
50303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
50313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOverLimit() {
50348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
50353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
50363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
50373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        List<Long> streamItemIds = Lists.newArrayList();
50393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX + 1 stream items.
50413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
50423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 6; i++) {
50433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
50443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
50453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemIds.add(ContentUris.parseId(resultUri));
50463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
50473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Long doomedStreamItemId = streamItemIds.get(0);
50483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // There should only be MAX items.  The oldest one should have been cleaned up.
50503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(
50513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
50523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
50533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY),
50543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItems._ID}, null, null, null);
50553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
50563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            while(c.moveToNext()) {
50573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                long streamItemId = c.getLong(0);
50583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                streamItemIds.remove(streamItemId);
50593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            }
50603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
50613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
50623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
50633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(1, streamItemIds.size());
50653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemOlderThanOldestInLimit() {
50688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
50693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
50703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
50713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Insert MAX stream items.
50733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long baseTime = System.currentTimeMillis();
50743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
50753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            values.put(StreamItems.TIMESTAMP, baseTime + i);
50763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
50773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertNotSame("Expected non-0 stream item ID to be inserted",
50783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    0L, ContentUris.parseId(resultUri));
50793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
50803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Now try to insert a stream item that's older.  It should be deleted immediately
50823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // and return an ID of 0.
50833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, baseTime - 1);
50843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = mResolver.insert(StreamItems.CONTENT_URI, values);
50853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertEquals(0L, ContentUris.parseId(resultUri));
50863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
50873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo insertion test cases.
50893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testInsertStreamItemsAndPhotosInBatch() throws Exception {
50918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
50923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemValues = buildGenericStreamItemValues();
50933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues streamItemPhotoValues = buildGenericStreamItemPhotoValues(0);
50943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
50953b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ArrayList<ContentProviderOperation> ops = Lists.newArrayList();
50963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ops.add(ContentProviderOperation.newInsert(
50973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
50983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
50993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        RawContacts.StreamItems.CONTENT_DIRECTORY))
51003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                .withValues(streamItemValues).build());
51013b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        for (int i = 0; i < 5; i++) {
51023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemPhotoValues.put(StreamItemPhotos.SORT_INDEX, i);
51033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_PHOTO_URI)
51043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValues(streamItemPhotoValues)
51053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .withValueBackReference(StreamItemPhotos.STREAM_ITEM_ID, 0)
51063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                    .build());
51073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
51083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
51093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that all five photos were inserted under the raw contact.
51113b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_URI, new String[]{StreamItems._ID},
51123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.RAW_CONTACT_ID + "=?", new String[]{String.valueOf(rawContactId)},
51133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
51143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = 0;
51153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
51163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(1, c.getCount());
51173b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.moveToFirst();
51183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            streamItemId = c.getLong(0);
51193b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
51203b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
51213b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
51223b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51233b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        c = mResolver.query(Uri.withAppendedPath(
51243b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
51256802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
51266802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                new String[]{StreamItemPhotos._ID, StreamItemPhotos.PHOTO_URI},
51273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null, null);
51283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
51293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals(5, c.getCount());
51306802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            byte[] expectedPhotoBytes = loadPhotoFromResource(
51316802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                    R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO);
51326802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            while (c.moveToNext()) {
51336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                String photoUri = c.getString(1);
513487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                EvenMoreAsserts.assertImageRawData(getContext(),
5135c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                        expectedPhotoBytes, mResolver.openInputStream(Uri.parse(photoUri)));
51366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro            }
51373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
51383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
51393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
51403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
51413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item update test cases.
51433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemById() {
51458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
51463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
51473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
51483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
51493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
51503b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId), values,
51513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
51523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
51533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
51543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
51553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
51563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testUpdateStreamItemWithContentValues() {
51588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
51593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
51603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
51613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
51623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems._ID, streamItemId);
51633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Goodbye world");
51643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(StreamItems.CONTENT_URI, values, null, null);
51653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
51663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
51673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), values);
51683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
51693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo update test cases.
51713b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoById() throws IOException {
51738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
51743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
51753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
51763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
51773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
51783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
51793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
51803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
51816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
51826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
51833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
51843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
51853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
51863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
51873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
51883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId);
51893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
51906802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
51913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
51926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
51936802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
51946802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
519587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5196c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
51976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
51983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
51993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52006802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testUpdateStreamItemPhotoWithContentValues() throws IOException {
52018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
52023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = buildGenericStreamItemValues();
52033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, values, null);
52043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(resultUri);
52053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues photoValues = buildGenericStreamItemPhotoValues(1);
52063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        resultUri = insertStreamItemPhoto(streamItemId, photoValues, null);
52073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(resultUri);
52083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        photoValues.put(StreamItemPhotos._ID, streamItemPhotoId);
52106802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(
52116802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                R.drawable.nebula, PhotoSize.ORIGINAL));
52123b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri =
52133b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                Uri.withAppendedPath(
52143b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
52153b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
52163b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.update(photoUri, photoValues, null, null);
52176802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        photoValues.remove(StreamItemPhotos.PHOTO);  // Removed during processing.
52183b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, photoValues);
52196802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
52206802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Check that the photo stored is the expected one.
52216802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        String displayPhotoUri = getStoredValue(photoUri, StreamItemPhotos.PHOTO_URI);
522287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
5223c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.nebula, PhotoSize.DISPLAY_PHOTO),
52246802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                mResolver.openInputStream(Uri.parse(displayPhotoUri)));
52253b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
52263b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item deletion test cases.
52283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemById() {
52308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
52313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
52323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri resultUri = insertStreamItem(rawContactId, firstValues, null);
52333b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long firstStreamItemId = ContentUris.parseId(resultUri);
52343b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52353b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
52363b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
52373b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
52383b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52393b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item.
52403b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, firstStreamItemId),
52413b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null, null);
52423b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52433b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
52443b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
52453b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
52463b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
52473b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
52483b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52493b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemWithSelection() {
52508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
52513b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstValues = buildGenericStreamItemValues();
52523b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, firstValues, null);
52533b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52543b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondValues = buildGenericStreamItemValues();
52553b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        secondValues.put(StreamItems.TEXT, "Goodbye world");
52563b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItem(rawContactId, secondValues, null);
52573b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52583b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Delete the first stream item with a custom selection.
52593b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(StreamItems.CONTENT_URI, StreamItems.TEXT + "=?",
52603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{"Hello world"});
52613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        // Check that only the second item remains.
52633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(Uri.withAppendedPath(
52643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
52653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                RawContacts.StreamItems.CONTENT_DIRECTORY), secondValues);
52663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
52673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    // Stream item photo deletion test cases.
52693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoById() {
52718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
52723b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
52733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
52743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemPhotoId = ContentUris.parseId(
52753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
52763b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(
52773b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(
52783b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        Uri.withAppendedPath(
52793b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
52803b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
52813b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                        streamItemPhotoId), null, null);
52823b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52833b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Cursor c = mResolver.query(StreamItems.CONTENT_PHOTO_URI,
52843b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                new String[]{StreamItemPhotos._ID},
52853b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItemPhotos.STREAM_ITEM_ID + "=?", new String[]{String.valueOf(streamItemId)},
52863b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                null);
52873b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        try {
52883b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            assertEquals("Expected photo to be deleted.", 0, c.getCount());
52893b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        } finally {
52903b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann            c.close();
52913b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        }
52923b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
52933b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
52943b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testDeleteStreamItemPhotoWithSelection() {
52958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
52963b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        long streamItemId = ContentUris.parseId(
52973b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
52983b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues firstPhotoValues = buildGenericStreamItemPhotoValues(0);
52993b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues secondPhotoValues = buildGenericStreamItemPhotoValues(1);
53003b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, firstPhotoValues, null);
53016802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        firstPhotoValues.remove(StreamItemPhotos.PHOTO);  // Removed while processing.
53023b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        insertStreamItemPhoto(streamItemId, secondPhotoValues, null);
53033b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        Uri photoUri = Uri.withAppendedPath(
53043b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
53053b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
53063b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        mResolver.delete(photoUri, StreamItemPhotos.SORT_INDEX + "=1", null);
53073b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
53083b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(photoUri, firstPhotoValues);
53093b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
53103b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
531182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    public void testDeleteStreamItemsWhenRawContactDeleted() {
53128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
531382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemUri = insertStreamItem(rawContactId,
531482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                buildGenericStreamItemValues(), mAccount);
531582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(ContentUris.parseId(streamItemUri),
531682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                        buildGenericStreamItemPhotoValues(0), mAccount);
531782780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        mResolver.delete(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
531882780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro                null, null);
531982780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
532082780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        ContentValues[] emptyValues = new ContentValues[0];
532182780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
532282780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        // The stream item and its photo should be gone.
532382780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemUri, emptyValues);
532482780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro        assertStoredValues(streamItemPhotoUri, emptyValues);
532582780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro    }
532682780691f1a3b4d8784e29a961b1140cd07bc9a8Dave Santoro
53273b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    public void testQueryStreamItemLimit() {
53283b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
53293b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.MAX_ITEMS, 5);
53303b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        assertStoredValues(StreamItems.CONTENT_LIMIT_URI, values);
53313b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
53323b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
53336802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // Tests for inserting or updating stream items as a side-effect of making status updates
53346802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    // (forward-compatibility of status updates into the new social stream API).
53356802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53366802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemInsertedOnStatusUpdate() {
53376802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53386802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
53396802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
53406802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
53416802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
53426802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
53436802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
53446802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                        StatusUpdates.CAPABILITY_HAS_VOICE);
53456802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53466802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
53476802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
53484747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "hacking");
5349d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
5350d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(String.valueOf(rawContactId))
5351d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
5352d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                expectedValues);
5353d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    }
5354d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
5355d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda    public void testStreamItemInsertedOnStatusUpdate_HtmlQuoting() {
5356d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
5357d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // This method of creating a raw contact automatically inserts a status update with
5358d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // the status message "hacking".
5359d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues values = new ContentValues();
5360d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        long rawContactId = createRawContact(values, "18004664411",
5361d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
5362d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.CAPABILITY_HAS_VOICE);
5363d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
5364d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        // Insert a new status update for the raw contact.
5365d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
5366d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda                StatusUpdates.INVISIBLE, "& <b> test &#39;", StatusUpdates.CAPABILITY_HAS_VOICE);
5367d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda
5368d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        ContentValues expectedValues = new ContentValues();
5369d5ef5903570e533a501abe6a8e3d533fdb5318fcFlavio Lerda        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
53704747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "&amp; &lt;b&gt; test &amp;#39;");
53716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
53726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
53736802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
53746802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
53756802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
53766802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53776802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    public void testStreamItemUpdatedOnSecondStatusUpdate() {
53786802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53796802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // This method of creating a raw contact automatically inserts a status update with
53806802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // the status message "hacking".
53816802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues values = new ContentValues();
53826802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        int chatMode = StatusUpdates.CAPABILITY_HAS_CAMERA | StatusUpdates.CAPABILITY_HAS_VIDEO |
53836802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.CAPABILITY_HAS_VOICE;
53846802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        long rawContactId = createRawContact(values, "18004664411",
53856802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0, chatMode);
53866802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53876802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        // Insert a new status update for the raw contact.
53886802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "goog411@acme.com",
53896802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                StatusUpdates.INVISIBLE, "finished hacking", chatMode);
53906802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
53916802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        ContentValues expectedValues = new ContentValues();
53926802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        expectedValues.put(StreamItems.RAW_CONTACT_ID, rawContactId);
53934747809486541f7a3d342d3e1dd48fb5ea255ad6Flavio Lerda        expectedValues.put(StreamItems.TEXT, "finished hacking");
53946802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        assertStoredValues(RawContacts.CONTENT_URI.buildUpon()
53956802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(String.valueOf(rawContactId))
53966802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY).build(),
53976802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                expectedValues);
53986802030a777c0c3ba1dc029c534cca4784260632Dave Santoro    }
53996802030a777c0c3ba1dc029c534cca4784260632Dave Santoro
540036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemReadRequiresReadSocialStreamPermission() {
54018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
540236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long contactId = queryContactId(rawContactId);
540336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String lookupKey = queryLookupKey(contactId);
540436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
540536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
540636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
540736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
540836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item in various ways.
540936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
541036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by contact ID requires social stream read permission",
541136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
541236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
541336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
541436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
541536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
541636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key requires social stream read permission",
541736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Contacts.CONTENT_LOOKUP_URI.buildUpon().appendPath(lookupKey)
541836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY).build(),
541936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
542036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
542136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
542236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by lookup key and ID requires social stream read permission",
542336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(Contacts.getLookupUri(contactId, lookupKey),
542436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Contacts.StreamItems.CONTENT_DIRECTORY),
542536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
542636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
542736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
542836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID requires social stream read permission",
542936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                Uri.withAppendedPath(
543036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
543136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
543236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
543336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
543436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream items by raw contact ID and stream item ID requires social " +
543536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        "stream read permission",
543636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(
543736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        Uri.withAppendedPath(
543836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
543936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                                RawContacts.StreamItems.CONTENT_DIRECTORY),
544036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        streamItemId), null, null, null, null);
544136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
544236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
544336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream items requires social stream read permission",
544436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI, null, null, null, null);
544536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
544636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
544736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying stream item by ID requires social stream read permission",
544836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
544936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
545036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
545136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
545236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoReadRequiresReadSocialStreamPermission() {
54538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
545436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
545536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
545636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
545736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
545836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
545936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
546036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        // Try selecting the stream item photo in various ways.
546136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
546236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
546336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
546436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY).build(),
546536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
546636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
546736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectSecurityException(
546836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                "Querying all stream item photos requires social stream read permission",
546936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StreamItems.CONTENT_URI.buildUpon()
547036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemId))
547136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
547236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        .appendPath(String.valueOf(streamItemPhotoId)).build(),
547336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                null, null, null, null);
547436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
547536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
547636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemModificationRequiresWriteSocialStreamPermission() {
54778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
547836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
547936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
548036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
548136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
548236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
548336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItem(rawContactId, buildGenericStreamItemValues(), null);
548436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert to stream without write social stream permission");
548536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
548636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
548736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
548836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
548936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
549036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItems.TEXT, "Goodbye world");
549136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
549236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    values, null, null);
549336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update stream without write social stream permission");
549436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
549536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
549636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
549736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
549836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
549936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    null, null);
550036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete from stream without write social stream permission");
550136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
550236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
550336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
550436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
550536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStreamItemPhotoModificationRequiresWriteSocialStreamPermission() {
55068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
550736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemId = ContentUris.parseId(
550836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItem(rawContactId, buildGenericStreamItemValues(), null));
550936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        long streamItemPhotoId = ContentUris.parseId(
551036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(0), null));
551136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
551236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
551336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        Uri photoUri = StreamItems.CONTENT_URI.buildUpon()
551436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemId))
551536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(StreamItems.StreamItemPhotos.CONTENT_DIRECTORY)
551636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                .appendPath(String.valueOf(streamItemPhotoId)).build();
551736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
551836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
551936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            insertStreamItemPhoto(streamItemId, buildGenericStreamItemPhotoValues(1), null);
552036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to insert photos without write social stream permission");
552136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
552236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
552336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
552436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
552536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            ContentValues values = new ContentValues();
552636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            values.put(StreamItemPhotos.PHOTO, loadPhotoFromResource(R.drawable.galaxy,
552736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                    PhotoSize.ORIGINAL));
552836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.update(photoUri, values, null, null);
552936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to update photos without write social stream permission");
553036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
553136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
553236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
553336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        try {
553436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            mResolver.delete(photoUri, null, null);
553536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro            fail("Should not be able to delete photos without write social stream permission");
553636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        } catch (SecurityException expected) {
553736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        }
553836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
553936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
554036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    public void testStatusUpdateDoesNotRequireReadOrWriteSocialStreamPermission() {
554136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
554236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        String handle1 = "test@gmail.com";
55438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
554436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertImHandle(rawContactId, protocol1, null, handle1);
554536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.READ_SOCIAL_STREAM");
554636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.removePermissions("android.permission.WRITE_SOCIAL_STREAM");
554736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
554836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
554936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA);
555036612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
555136612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        mActor.addPermissions("android.permission.READ_SOCIAL_STREAM");
555236612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
555336612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        ContentValues expectedValues = new ContentValues();
555436612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        expectedValues.put(StreamItems.TEXT, "Green");
555536612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro        assertStoredValues(Uri.withAppendedPath(
555636612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
555736612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro                        RawContacts.StreamItems.CONTENT_DIRECTORY), expectedValues);
555836612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro    }
555936612112760df799ef89f7e324e5dfabd5ca0d2bDave Santoro
55603b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemValues() {
55613b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
55623b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TEXT, "Hello world");
55633b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
55643b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItems.COMMENTS, "Reshared by 123 others");
55653b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
55663b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
55673b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
55683b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    private ContentValues buildGenericStreamItemPhotoValues(int sortIndex) {
55693b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        ContentValues values = new ContentValues();
55703b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        values.put(StreamItemPhotos.SORT_INDEX, sortIndex);
55716802030a777c0c3ba1dc029c534cca4784260632Dave Santoro        values.put(StreamItemPhotos.PHOTO,
55726802030a777c0c3ba1dc029c534cca4784260632Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL));
55733b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann        return values;
55743b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann    }
55753b505de6c622d20d40b85b361c1437a89aef82deDaniel Lehmann
557682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov    public void testSingleStatusUpdateRowPerContact() {
5577bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        int protocol1 = Im.PROTOCOL_GOOGLE_TALK;
5578bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        String handle1 = "test@gmail.com";
5579bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
55808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
55814dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId1, protocol1, null, handle1);
5582bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5583aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AVAILABLE, "Green",
5584aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5585aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.AWAY, "Yellow",
5586aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5587aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(protocol1, null, handle1, StatusUpdates.INVISIBLE, "Red",
5588aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5589bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5590af088aeb51685eed17580edc04b495d12232ecf9Dmitri Plotnikov        Cursor c = queryContact(queryContactId(rawContactId1),
559182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov                new String[] {Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS});
55924a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        assertEquals(1, c.getCount());
5593bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5594bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar        c.moveToFirst();
559582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(StatusUpdates.INVISIBLE, c.getInt(0));
559682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals("Red", c.getString(1));
55970265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        c.close();
5598bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar    }
5599bc5c799a52b5bde2f273efd118ebe2228c3d8f15Evan Millar
5600d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void updateSendToVoicemailAndRingtone(long contactId, boolean sendToVoicemail,
5601d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String ringtone) {
5602d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        ContentValues values = new ContentValues();
5603d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
5604d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (ringtone != null) {
5605d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
5606d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5607d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5608d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        final Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
5609d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        int count = mResolver.update(uri, values, null, null);
5610d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(1, count);
56118c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    }
56128c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
56138c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov    private void updateSendToVoicemailAndRingtoneWithSelection(long contactId,
56148c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            boolean sendToVoicemail, String ringtone) {
56158c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        ContentValues values = new ContentValues();
56168c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        values.put(Contacts.SEND_TO_VOICEMAIL, sendToVoicemail);
56178c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        if (ringtone != null) {
56188c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov            values.put(Contacts.CUSTOM_RINGTONE, ringtone);
56198c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        }
56208c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov
56218c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        int count = mResolver.update(Contacts.CONTENT_URI, values, Contacts._ID + "=" + contactId,
56228c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov                null);
56238c4f838f899daadb6f46f8c27ab7636023e39c38Dmitri Plotnikov        assertEquals(1, count);
5624d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
5625d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov
5626d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov    private void assertSendToVoicemailAndRingtone(long contactId, boolean expectedSendToVoicemail,
5627d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            String expectedRingtone) {
5628d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Cursor c = queryContact(contactId);
5629d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertTrue(c.moveToNext());
5630d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        int sendToVoicemail = c.getInt(c.getColumnIndex(Contacts.SEND_TO_VOICEMAIL));
5631d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        assertEquals(expectedSendToVoicemail ? 1 : 0, sendToVoicemail);
5632d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        String ringtone = c.getString(c.getColumnIndex(Contacts.CUSTOM_RINGTONE));
5633d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        if (expectedRingtone == null) {
5634d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertNull(ringtone);
5635d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        } else {
5636d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov            assertTrue(ArrayUtils.contains(expectedRingtone.split(","), ringtone));
5637d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        }
5638d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov        c.close();
5639d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov    }
56409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
56410be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    public void testContactVisibilityUpdateOnMembershipChange() {
56428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
56430be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
56440be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56450be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long visibleGroupId = createGroup(mAccount, "123", "Visible", 1);
56460be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        long invisibleGroupId = createGroup(mAccount, "567", "Invisible", 0);
56470be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56480be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership1 = insertGroupMembership(rawContactId, visibleGroupId);
56490be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
56500be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56510be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        Uri membership2 = insertGroupMembership(rawContactId, invisibleGroupId);
56520be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
56530be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56540be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.delete(membership1, null, null);
56550be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "0");
56560be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56570be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        ContentValues values = new ContentValues();
56580be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        values.put(GroupMembership.GROUP_ROW_ID, visibleGroupId);
56590be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56600be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        mResolver.update(membership2, values, null, null);
56610be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertVisibility(rawContactId, "1");
56620be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
56630be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56640be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    private void assertVisibility(long rawContactId, String expectedValue) {
56650be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, Contacts._ID + "=" + queryContactId(rawContactId),
56660be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov                null, Contacts.IN_VISIBLE_GROUP, expectedValue);
56670be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov    }
56680be993f8ef0078b9825a5ffe6add08a6786d8dacDmitri Plotnikov
56690db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    public void testSupplyingBothValuesAndParameters() throws Exception {
56700db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Account account = new Account("account 1", "type%/:1");
56710db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        Uri uri = ContactsContract.Groups.CONTENT_URI.buildUpon()
56720db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_NAME, account.name)
56730db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.Groups.ACCOUNT_TYPE, account.type)
56740db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
56750db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov                .build();
56760db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
56770db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
56780db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
56790db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
56800db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some id");
56810db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some name");
56820db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
56830db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
56840db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
56850db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
56860db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder = ContentProviderOperation.newInsert(uri);
56870db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type + "diff");
56880db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
56890db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.SYSTEM_ID, "some other id");
56900db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.TITLE, "some other name");
56910db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        builder.withValue(ContactsContract.Groups.GROUP_VISIBLE, 1);
56920db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
56930db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        try {
56940db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            mResolver.applyBatch(ContactsContract.AUTHORITY, Lists.newArrayList(builder.build()));
56950db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            fail("Expected IllegalArgumentException");
56960db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        } catch (IllegalArgumentException ex) {
56970db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov            // Expected
56980db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov        }
56990db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov    }
57000db2cea4e4a8082ca8dd7d2023b9f3025c2768d8Dmitri Plotnikov
5701a549eb3c9627862a3e45d910d5c981191086a949Dmitri Plotnikov    public void testContentEntityIterator() {
57029261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        // create multiple contacts and check that the selected ones are returned
57039261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long id;
57049261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57059261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId1 = createGroup(mAccount, "gsid1", "title1");
57069261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        long groupId2 = createGroup(mAccount, "gsid2", "title2");
57079261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID, "c0");
57093cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertGroupMembership(id, "gsid1");
57103cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertEmail(id, "c0@email.com");
57113cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        insertPhoneNumber(id, "5551212c0");
57129261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c1 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
57148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c1");
57159261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_0 = insertGroupMembership(id, "gsid1");
57169261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_1 = insertGroupMembership(id, "gsid2");
57179261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_2 = insertEmail(id, "c1@email.com");
57189261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_1_3 = insertPhoneNumber(id, "5551212c1");
57199261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c2 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
57218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c2");
57229261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_0 = insertGroupMembership(id, "gsid1");
57239261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_1 = insertEmail(id, "c2@email.com");
57249261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_2_2 = insertPhoneNumber(id, "5551212c2");
57259261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long c3 = id = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.SOURCE_ID,
57278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                "c3");
57289261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_0 = insertGroupMembership(id, groupId2);
57299261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_1 = insertEmail(id, "c3@email.com");
57309261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Uri id_3_2 = insertPhoneNumber(id, "5551212c3");
57319261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
573262318e1ea8306142a10526534b7d83560ecf5b3aFred Quintana        EntityIterator iterator = RawContacts.newEntityIterator(mResolver.query(
57338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.maybeAddAccountQueryParameters(RawContactsEntity.CONTENT_URI, mAccount),
57348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                null, RawContacts.SOURCE_ID + " in ('c1', 'c2', 'c3')", null, null));
57359261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        Entity entity;
57369261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        ContentValues[] subValues;
57379261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
57386cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c1, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
57399261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
57409261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(4, subValues.length);
57419261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
57429261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_0,
57439261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
57449261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
57459261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], GroupMembership.CONTENT_ITEM_TYPE,
57469261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_1,
57479261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
57489261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
57499261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Email.CONTENT_ITEM_TYPE,
57509261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_2,
57519261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c1@email.com");
57529261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[3], Phone.CONTENT_ITEM_TYPE,
57539261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_1_3,
57549261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c1");
57559261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57569261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
57576cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c2, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
57589261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
57599261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
57609261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
57619261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_0,
57629261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId1,
57639261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid1");
57649261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
57659261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_1,
57669261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c2@email.com");
57679261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
57689261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_2_2,
57699261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c2");
57709261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57719261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        entity = iterator.next();
57726cffee46a1334d2b3ed19f436b27638451541044Dmitri Plotnikov        assertEquals(c3, (long) entity.getEntityValues().getAsLong(RawContacts._ID));
57739261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        subValues = asSortedContentValuesArray(entity.getSubValues());
57749261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertEquals(3, subValues.length);
57759261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[0], GroupMembership.CONTENT_ITEM_TYPE,
57769261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_0,
57779261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_ROW_ID, groupId2,
57789261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                GroupMembership.GROUP_SOURCE_ID, "gsid2");
57799261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[1], Email.CONTENT_ITEM_TYPE,
57809261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_1,
57819261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "c3@email.com");
57829261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertDataRow(subValues[2], Phone.CONTENT_ITEM_TYPE,
57839261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Data._ID, id_3_2,
57849261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana                Email.DATA, "5551212c3");
57859261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana
57869261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana        assertFalse(iterator.hasNext());
57873cfe8d532d509fbbe605454e3a32b2361b7e1501Dmitri Plotnikov        iterator.close();
57889261b2141aa90a4fed632fd6da03026d4c216280Fred Quintana    }
578920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
579020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    public void testDataCreateUpdateDeleteByMimeType() throws Exception {
57918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
579220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
579320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        ContentValues values = new ContentValues();
57945ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
579520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
579620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
579720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
579820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
579920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "old1");
580020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "old2");
580120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "old3");
580220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "old4");
580320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "old5");
580420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "old6");
580520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "old7");
580620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "old8");
580720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "old9");
580820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "old10");
580920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "old11");
581020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "old12");
581120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "old13");
581220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "old14");
581320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "old15");
581420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        Uri uri = mResolver.insert(Data.CONTENT_URI, values);
581520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
581681d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
581720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
581820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.clear();
581920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "newpackage");
582020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 0);
582120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 0);
582220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA1, "new1");
582320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA2, "new2");
582420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA3, "new3");
582520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA4, "new4");
582620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA5, "new5");
582720a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA6, "new6");
582820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA7, "new7");
582920a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA8, "new8");
583020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA9, "new9");
583120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA10, "new10");
583220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA11, "new11");
583320a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA12, "new12");
583420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA13, "new13");
583520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA14, "new14");
583620a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        values.put(Data.DATA15, "new15");
58375ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        mResolver.update(Data.CONTENT_URI, values, Data.RAW_CONTACT_ID + "=" + rawContactId +
583820a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                " AND " + Data.MIMETYPE + "='testmimetype'", null);
583981d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
584070b5ee6864cb3368d24a9e876fb93008997b12dfDmitri Plotnikov
584120a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertStoredValues(uri, values);
584220a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
58435ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        int count = mResolver.delete(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
584420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov                + " AND " + Data.MIMETYPE + "='testmimetype'", null);
584520a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov        assertEquals(1, count);
58465ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        assertEquals(0, getCount(Data.CONTENT_URI, Data.RAW_CONTACT_ID + "=" + rawContactId
584733b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                        + " AND " + Data.MIMETYPE + "='testmimetype'", null));
584881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
584933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov    }
585020a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov
585189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    public void testRawContactQuery() {
585289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account1 = new Account("a", "b");
585389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Account account2 = new Account("c", "d");
58548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, account1);
58558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, account2);
585689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
58578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri1 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account1);
58588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri2 = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI, account2);
585989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri1, null, null));
586089c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertEquals(1, getCount(uri2, null, null));
586189c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri1, RawContacts._ID, rawContactId1) ;
586289c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(uri2, RawContacts._ID, rawContactId2) ;
586389c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
586489c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri1 = ContentUris.withAppendedId(uri1, rawContactId1);
586589c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        Uri rowUri2 = ContentUris.withAppendedId(uri2, rawContactId2);
586689c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri1, RawContacts._ID, rawContactId1) ;
586789c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov        assertStoredValue(rowUri2, RawContacts._ID, rawContactId2) ;
586889c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov    }
586989c626eb655440c86a2e5df076e83708c1b32c17Dmitri Plotnikov
5870373f7d2adc36680c31ff33e9ee12be865af6b5fbDmitri Plotnikov    public void testRawContactDeletion() {
58718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
58725ef0401c311c62e53bde415b99cbb0ff83b0a9a2Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
587333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
58744dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
587582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5876aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5877aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5878a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId);
5879a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
588033b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
588133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
588282bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
58834dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
588433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
588533b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(uri, null, null);
588633b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
58875870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
588881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
588933b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov
5890e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
589133b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
589233b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
589333b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov        assertEquals(0, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
589433b41fdb8d7c3c654cb070799c9d6e2b4ab16078Dmitri Plotnikov                null, null));
589582bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
58964dcd106ccc27dbbfaae86baf0cd57beb42c27cccDmitri Plotnikov                + rawContactId, null));
5897a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
589881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
5899a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    }
5900a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5901a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov    public void testRawContactDeletionKeepingAggregateContact() {
59028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
59038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, mAccount);
590447fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
590547fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
5906a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5907a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
5908a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov
5909a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
5910e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri permanentDeletionUri = setCallerIsSyncAdapter(uri, mAccount);
5911a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        mResolver.delete(permanentDeletionUri, null, null);
5912a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(0, getCount(uri, null, null));
5913a5bfaf55790262eea97de432d9e7f313c219c066Dmitri Plotnikov        assertEquals(1, getCount(Contacts.CONTENT_URI, Contacts._ID + "=" + contactId, null));
591420a94c86ede7380c8dd8df2f6a72b3c00ac1bed8Dmitri Plotnikov    }
59151fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
59165f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountParam() {
59178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
5918e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
5919e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5920e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        insertImHandle(rawContactId, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
592182bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
5922aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
5923aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
5924e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        assertEquals(1, getCount(Uri.withAppendedPath(uri, RawContacts.Data.CONTENT_DIRECTORY),
5925e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                null, null));
592682bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(1, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
5927e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                + rawContactId, null));
5928e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5929e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Do not delete if we are deleting with wrong account.
5930e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithWrongAccountUri =
5931e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5932e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccountTwo.name)
5933e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccountTwo.type)
5934e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
59355f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(deleteWithWrongAccountUri, null, null);
59365f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
5937e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
59385870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "0");
5939e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
5940e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        // Delete if we are deleting with correct account.
5941e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong        Uri deleteWithCorrectAccountUri =
5942e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong            RawContacts.CONTENT_URI.buildUpon()
5943e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, mAccount.name)
5944e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, mAccount.type)
5945e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong                .build();
59465f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(deleteWithCorrectAccountUri, null, null);
59475f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
59485f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
59495f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "1");
59505f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    }
59515f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
59525f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki    public void testRawContactDeletion_byAccountSelection() {
59538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
59545f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        Uri uri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
59555f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
59565f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Do not delete if we are deleting with wrong account.
59575f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        int numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
59585f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
59595f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccountTwo.name, mAccountTwo.type});
59605f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(0, numDeleted);
59615f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
59625f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertStoredValue(uri, RawContacts.DELETED, "0");
59635f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki
59645f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        // Delete if we are deleting with correct account.
59655f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        numDeleted = mResolver.delete(RawContacts.CONTENT_URI,
59665f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                RawContacts.ACCOUNT_NAME + "=? AND " + RawContacts.ACCOUNT_TYPE + "=?",
59675f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki                new String[] {mAccount.name, mAccount.type});
59685f673b204620c4c241b3b39c6ac0ee063d22f13bMakoto Onuki        assertEquals(1, numDeleted);
5969e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
59705870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
5971e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong    }
5972e2579e029472f76b2dfda141444d775c67da0ec8Cynthia Wong
59739ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
59749ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#stringToAccounts} and
59759ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#accountsToString}.
59769ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
59779ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testAccountsToString() {
59789ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> EXPECTED_0 = Sets.newHashSet();
59798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
59808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
59818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> EXPECTED_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2);
59829ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
59839ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Set<Account> ACTUAL_0 = Sets.newHashSet();
59848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1 = Sets.newHashSet(TestUtil.ACCOUNT_1);
59858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_2 = Sets.newHashSet(TestUtil.ACCOUNT_2);
59868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Set<Account> ACTUAL_1_2 = Sets.newHashSet(TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1);
59879ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
59889ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_0)));
59899ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1)));
59909ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_2)));
59919ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_0.equals(accountsToStringToAccounts(ACTUAL_1_2)));
59929ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
59939ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_0)));
59949ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1)));
59959ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_2)));
59969ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1.equals(accountsToStringToAccounts(ACTUAL_1_2)));
59979ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
59989ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_0)));
59999ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1)));
60009ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_2)));
60019ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
60029ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60039ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_0)));
60049ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1)));
60059ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_2)));
60069ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(EXPECTED_1_2.equals(accountsToStringToAccounts(ACTUAL_1_2)));
60079ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60089ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        try {
60099ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            ContactsProvider2.stringToAccounts("x");
60109ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki            fail("Didn't throw for malformed input");
60119ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        } catch (IllegalArgumentException expected) {
60129ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        }
60139ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
60149ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60159ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    private static final Set<Account> accountsToStringToAccounts(Set<Account> accounts) {
60169ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        return ContactsProvider2.stringToAccounts(ContactsProvider2.accountsToString(accounts));
60179ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
60189ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60199ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    /**
60209ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * Test for {@link ContactsProvider2#haveAccountsChanged} and
60219ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     * {@link ContactsProvider2#saveAccounts}.
60229ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki     */
60239ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    public void testHaveAccountsChanged() {
60249ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsProvider2 cp = (ContactsProvider2) getProvider();
60259ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60269ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final Account[] ACCOUNTS_0 = new Account[] {};
60278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1 = new Account[] {TestUtil.ACCOUNT_1};
60288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2 = new Account[] {TestUtil.ACCOUNT_2};
60298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_1_2 = new Account[] {TestUtil.ACCOUNT_1, TestUtil.ACCOUNT_2};
60308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Account[] ACCOUNTS_2_1 = new Account[] {TestUtil.ACCOUNT_2, TestUtil.ACCOUNT_1};
60319ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60329ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_1
60339ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60349ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
60359ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1);
60369ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1));
60379ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60389ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Add ACCOUNT_2
60399ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60409ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1_2));
60419ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
60429ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2_1));
60439ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_1_2);
60449ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_1_2));
60459ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // (try with reverse order)
60469ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2_1));
60479ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60489ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_1
60499ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60509ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_2));
60519ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_2);
60529ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_2));
60539ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60549ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Remove ACCOUNT_2
60559ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60569ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
60579ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        cp.saveAccounts(ACCOUNTS_0);
60589ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertFalse(cp.haveAccountsChanged(ACCOUNTS_0));
60599ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60609ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // Test with malformed DB property.
60619ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60629ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        final ContactsDatabaseHelper dbHelper = cp.getThreadActiveDatabaseHelperForTest();
60639ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        dbHelper.setProperty(DbProperties.KNOWN_ACCOUNTS, "x");
60649ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
60659ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        // With malformed property the method always return true.
60669ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_0));
60679ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki        assertTrue(cp.haveAccountsChanged(ACCOUNTS_1));
60689ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki    }
60699ba8463dd030e5e26a4f99dfe2a6ad52b2410d73Makoto Onuki
6070627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov    public void testAccountsUpdated() {
607170d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // This is to ensure we do not delete contacts with null, null (account name, type)
607270d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        // accidentally.
60738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
607470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        insertPhoneNumber(rawContactId3, "5234567890");
6075627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        Uri rawContact3 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId3);
6076743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
607770d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
607870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong        ContactsProvider2 cp = (ContactsProvider2) getProvider();
6079bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount, mAccountTwo});
6080743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount, mAccountTwo});
6081743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        assertEquals(1, getCount(RawContacts.CONTENT_URI, null, null));
6082dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_NAME, null);
6083dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertStoredValue(rawContact3, RawContacts.ACCOUNT_TYPE, null);
608470d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
60858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount);
6086743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId1, "account1@email.com");
60878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
6088743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertEmail(rawContactId2, "account2@email.com");
6089743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertImHandle(rawContactId2, Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com");
6090743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, "deleteme@android.com",
6091aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.AVAILABLE, null,
6092aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                StatusUpdates.CAPABILITY_HAS_CAMERA);
6093743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov
6094bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{mAccount});
6095743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{mAccount});
6096627152453c692915ac79191acd1d2d2a4dd6fb0dDmitri Plotnikov        assertEquals(2, getCount(RawContacts.CONTENT_URI, null, null));
609782bd858c9911dfbd8dca52dc276333768b0a429eDmitri Plotnikov        assertEquals(0, getCount(StatusUpdates.CONTENT_URI, PresenceColumns.RAW_CONTACT_ID + "="
609870d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong                + rawContactId2, null));
609970d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong    }
610070d2ff8c87961703351b223ce8b15342fe795a0bCynthia Wong
610133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    public void testAccountDeletion() {
610233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Account readOnlyAccount = new Account("act", READ_ONLY_ACCOUNT_TYPE);
610333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        ContactsProvider2 cp = (ContactsProvider2) getProvider();
6104bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount, mAccount});
610533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount, mAccount});
610633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
61078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
61088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                readOnlyAccount);
610933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri1 = insertPhoto(rawContactId1);
61108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "john", "doe",
61118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                mAccount);
611233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        Uri photoUri2 = insertPhoto(rawContactId2);
611333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        storeValue(photoUri2, Photo.IS_SUPER_PRIMARY, "1");
611433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
611533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertAggregated(rawContactId1, rawContactId2);
611633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
611733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
611833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
611933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the writable account
612033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
612133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
612233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
612333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "john doe");
612433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
612533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the one we marked as super-primary
612633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
612733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri2));
612833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
6129bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[]{readOnlyAccount});
613033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // Remove the writable account
613133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        cp.onAccountsUpdated(new Account[]{readOnlyAccount});
613233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
613333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The display name should come from the remaining account
613433fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Uri.withAppendedPath(
613533fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
613633fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.Data.CONTENT_DIRECTORY),
613733fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.DISPLAY_NAME, "John Doe");
613833fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
613933fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        // The photo should be the remaining one
614033fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov        assertStoredValue(Contacts.CONTENT_URI, contactId,
614133fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov                Contacts.PHOTO_ID, ContentUris.parseId(photoUri1));
614233fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov    }
614333fd566fb6eebdd40a900c0c8a2f6dca894d7829Dmitri Plotnikov
6144c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    public void testStreamItemsCleanedUpOnAccountRemoval() {
6145c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account doomedAccount = new Account("doom", "doom");
6146c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Account safeAccount = mAccount;
6147c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContactsProvider2 cp = (ContactsProvider2) getProvider();
6148c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{doomedAccount, safeAccount});
6149c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{doomedAccount, safeAccount});
6150c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6151c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a doomed raw contact, stream item, and photo.
61528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long doomedRawContactId = RawContactUtil.createRawContactWithName(mResolver, doomedAccount);
6153c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemUri =
6154c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(doomedRawContactId, buildGenericStreamItemValues(), doomedAccount);
6155c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long doomedStreamItemId = ContentUris.parseId(doomedStreamItemUri);
6156c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri doomedStreamItemPhotoUri = insertStreamItemPhoto(
6157c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                doomedStreamItemId, buildGenericStreamItemPhotoValues(0), doomedAccount);
6158c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6159c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Create a safe raw contact, stream item, and photo.
61608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long safeRawContactId = RawContactUtil.createRawContactWithName(mResolver, safeAccount);
6161c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemUri =
6162c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                insertStreamItem(safeRawContactId, buildGenericStreamItemValues(), safeAccount);
6163c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemId = ContentUris.parseId(safeStreamItemUri);
6164c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        Uri safeStreamItemPhotoUri = insertStreamItemPhoto(
6165c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeStreamItemId, buildGenericStreamItemPhotoValues(0), safeAccount);
6166c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        long safeStreamItemPhotoId = ContentUris.parseId(safeStreamItemPhotoUri);
6167c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6168c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Remove the doomed account.
6169c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        mActor.setAccounts(new Account[]{safeAccount});
6170c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        cp.onAccountsUpdated(new Account[]{safeAccount});
6171c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6172c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the doomed stuff has all been nuked.
6173c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        ContentValues[] noValues = new ContentValues[0];
6174c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(ContentUris.withAppendedId(RawContacts.CONTENT_URI, doomedRawContactId),
6175c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                noValues);
6176c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemUri, noValues);
6177c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValues(doomedStreamItemPhotoUri, noValues);
6178c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6179c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        // Check that the safe stuff lives on.
6180c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(RawContacts.CONTENT_URI, safeRawContactId, RawContacts._ID,
6181c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro                safeRawContactId);
6182c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemUri, StreamItems._ID, safeStreamItemId);
6183c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro        assertStoredValue(safeStreamItemPhotoUri, StreamItemPhotos._ID, safeStreamItemPhotoId);
6184c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro    }
6185c88cc79e0e19b8299a2a356c7d70b48f70b4a93eDave Santoro
6186cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    public void testContactDeletion() {
61878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
61888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_1);
61898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver, "John", "Doe",
61908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                TestUtil.ACCOUNT_2);
6191cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
6192cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
6193cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
6194cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        mResolver.delete(ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), null, null);
6195cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
6196cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1),
6197cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
6198cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov        assertStoredValue(ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2),
6199cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov                RawContacts.DELETED, "1");
6200cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov    }
6201cb144e1429596701603c016f4a078f6331e6481dDmitri Plotnikov
620273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov    public void testMarkAsDirtyParameter() {
62038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
620473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
620573776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
62068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
620773776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        clearDirty(rawContactUri);
6208e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        Uri updateUri = setCallerIsSyncAdapter(uri, mAccount);
620973776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov
621073776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        ContentValues values = new ContentValues();
621173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Dough");
621273776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        mResolver.update(updateUri, values, null, null);
62135870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, StructuredName.FAMILY_NAME, "Dough");
621473776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(rawContactUri, false);
621581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
62161fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
62171fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
621861d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDirtyAndVersion() {
62198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
6220d3fde755e73cd3912a488e7cb7d412d3c5f6ca94Dmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawContactId);
622173776ffd5c00e94db987ee30864e9c7a8396d22dDmitri Plotnikov        assertDirty(uri, false);
62221fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
62231fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
62241fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ContentValues values = new ContentValues();
62251fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.DIRTY, 0);
62261fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        values.put(ContactsContract.RawContacts.SEND_TO_VOICEMAIL, 1);
622761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.AGGREGATION_MODE,
6228c100221f706afc08409e8317a27d6850b11c54d3Omari Stephens                RawContacts.AGGREGATION_MODE_IMMEDIATE);
622961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(ContactsContract.RawContacts.STARRED, 1);
62301fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(1, mResolver.update(uri, values, null, null));
62311fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
62321fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
62331fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
623481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(false);
62351fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
623661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "goo@woo.com");
623761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
623881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
62391fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
62401fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
624161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
62421fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
624361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values = new ContentValues();
624461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        values.put(Email.DATA, "goo@hoo.com");
624561d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.update(emailUri, values, null, null);
62461fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
624781d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
62481fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
62491fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
625061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
62511fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
625261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(emailUri, null, null);
62531fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
625481d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
62551fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        ++version;
62561fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
625761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    }
62581fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
625961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactClearDirty() {
62608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
626161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
626261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
626361d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        long version = getVersion(uri);
626461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        insertEmail(rawContactId, "goo@woo.com");
62651fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, true);
626661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
62671fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
62681fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
62691fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        clearDirty(uri);
62701fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertDirty(uri, false);
62711fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        assertEquals(version, getVersion(uri));
62721fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
62731fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana
627461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov    public void testRawContactDeletionSetsDirty() {
62758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId = RawContactUtil.createRawContact(mResolver, mAccount);
62761fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        Uri uri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI,
627761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov                rawContactId);
62781fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana        long version = getVersion(uri);
627961d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        clearDirty(uri);
628061d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, false);
628161d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov
628261d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        mResolver.delete(uri, null, null);
62835870f2dcc2ac7715b2c078a886ee346622e7887eDmitri Plotnikov        assertStoredValue(uri, RawContacts.DELETED, "1");
628461d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertDirty(uri, true);
628581d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
628661d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        version++;
628761d61cb4d13a33c5581765fb4c0f1b3c0b2cdf4cDmitri Plotnikov        assertEquals(version, getVersion(uri));
62881fd9b53d9e5d8ea87b69a51fb084c6f0d9f7c93eFred Quintana    }
62894a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
62909fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutName() {
62919fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
62929fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
62939fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
62949fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri phoneUri = insertPhoneNumber(rawContactId, "555-123-45678", true);
62959fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
62969fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
62979fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
62989fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
62999fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
63009fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
63019fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
63029fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
63039fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
63049fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    public void testDeleteContactWithoutAnyData() {
63059fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, new ContentValues());
63069fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
63079fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
63089fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        long contactId = queryContactId(rawContactId);
63099fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
63109fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
63119fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
63129fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        int numDeleted = mResolver.delete(lookupUri, null, null);
63139fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann        assertEquals(1, numDeleted);
63149fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann    }
63159fcf109b56cec0aad05322a3b4594228ea06d859Daniel Lehmann
631660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testDeleteContactWithEscapedUri() {
631760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
631860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
631960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
632060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
632160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
632260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
632360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
632460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
632560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, mResolver.delete(lookupUri, null, null));
632660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
632760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
632860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    public void testQueryContactWithEscapedUri() {
632960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        ContentValues values = new ContentValues();
633060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        values.put(RawContacts.SOURCE_ID, "!@#$%^&*()_+=-/.,<>?;'\":[]}{\\|`~");
633160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
633260de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long rawContactId = ContentUris.parseId(rawContactUri);
633360de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
633460de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        long contactId = queryContactId(rawContactId);
633560de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
633660de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
633760de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        Cursor c = mResolver.query(lookupUri, null, null, null, "");
633860de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        assertEquals(1, c.getCount());
633960de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann        c.close();
634060de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann    }
634160de6f6c3c70e53b603a47b0efc80993353a8368Daniel Lehmann
6342074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    public void testGetPhotoUri() {
6343074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        ContentValues values = new ContentValues();
6344074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
6345074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
63468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
6347f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6348f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
6349f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId)}, Photo.PHOTO_FILE_ID);
6350f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId)
6351f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
6352074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
63533d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov        assertStoredValue(
63543d67ff829e8acb0f650f155c3c0d377c0f46507aDmitri Plotnikov                ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(rawContactId)),
6355f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI, photoUri);
6356074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov    }
6357074cf38e39d500e92fa851a171d0378ab2c528c2Dmitri Plotnikov
6358bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    public void testGetPhotoViaLookupUri() throws IOException {
63598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
6360bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        long contactId = queryContactId(rawContactId);
6361bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6362bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri lookupUri = Contacts.getLookupUri(mResolver, contactUri);
6363bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        String lookupKey = lookupUri.getPathSegments().get(2);
6364bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
6365bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        byte[] thumbnail = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL);
6366bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
6367bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Two forms of lookup key URIs should be valid - one with the contact ID, one without.
6368bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithId = Uri.withAppendedPath(lookupUri, "photo");
6369bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        Uri photoLookupUriWithoutId = Contacts.CONTENT_LOOKUP_URI.buildUpon()
6370bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro                .appendPath(lookupKey).appendPath("photo").build();
6371bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
6372bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try retrieving as a data record.
6373bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        ContentValues values = new ContentValues();
6374bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        values.put(Photo.PHOTO, thumbnail);
6375bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithId, values);
6376bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        assertStoredValues(photoLookupUriWithoutId, values);
6377bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
6378bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro        // Try opening as an input stream.
637987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6380c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithId));
638187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6382c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                thumbnail, mResolver.openInputStream(photoLookupUriWithoutId));
6383bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro    }
6384bd20dbedba706fdf2db7acb1c7d4391e57129d44Dave Santoro
6385ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    public void testInputStreamForPhoto() throws Exception {
63868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
6387f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6388f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6389f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId);
6390f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_URI));
6391f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoThumbnailUri = Uri.parse(getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI));
6392e8d2c8276d6331843410c97751e46fc50b257379Dmitri Plotnikov
639387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Check the thumbnail.
639487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
6395f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoThumbnailUri));
639687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki
639787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // Then check the display photo.  Note because we only inserted a small photo, but not a
639887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // display photo, this returns the thumbnail image itself, which was compressed at
639987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // the thumnail compression rate, which is why we compare to
640087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL) rather than loadTestPhoto(PhotoSize.DISPLAY_PHOTO)
640187426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // here.
640287426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // (In other words, loadTestPhoto(PhotoSize.DISPLAY_PHOTO) returns the same photo as
640387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        // loadTestPhoto(PhotoSize.THUMBNAIL), except it's compressed at a lower compression rate.)
640487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(), loadTestPhoto(PhotoSize.THUMBNAIL),
640587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                mResolver.openInputStream(photoUri));
6406ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert    }
6407ac13ddd04d665442de846b59234bdc936a6699b4Bjorn Bringert
6408732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    public void testSuperPrimaryPhoto() {
64098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
6410f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri1 = insertPhoto(rawContactId1, R.drawable.earth_normal);
6411732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId1 = ContentUris.parseId(photoUri1);
6412732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
64138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
6414f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri2 = insertPhoto(rawContactId2, R.drawable.earth_normal);
6415732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        long photoId2 = ContentUris.parseId(photoUri2);
6416732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
6417732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
6418732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
6419732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
6420732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
6421732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
6422f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6423f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 = getStoredLongValue(Data.CONTENT_URI, Data._ID + "=?",
6424f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(photoId1)}, Photo.PHOTO_FILE_ID);
6425f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = ContentUris.withAppendedId(DisplayPhoto.CONTENT_URI, photoFileId1)
6426f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .toString();
6427732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
6428f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValue(contactUri, Contacts.PHOTO_URI, photoUri);
6429732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
6430732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE,
6431732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                rawContactId1, rawContactId2);
6432732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
643377e675b050770c1bd68906c25859d7cdf8ea49dbZheng Fu        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
643477e675b050770c1bd68906c25859d7cdf8ea49dbZheng Fu                rawContactId1, rawContactId2);
6435732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        ContentValues values = new ContentValues();
6436732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
6437732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri2, values, null, null);
6438732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
6439732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI,
6440732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov                queryContactId(rawContactId1));
6441732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId2);
6442732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
6443732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        mResolver.update(photoUri1, values, null, null);
6444732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.PHOTO_ID, photoId1);
6445732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov    }
6446732961a5b936d316482f9ded6bfc5fe1c99a65c8Dmitri Plotnikov
64478e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    public void testUpdatePhoto() {
64488e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        ContentValues values = new ContentValues();
64498e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
64508e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
64518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, "John", "Doe");
64528e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
64538e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri twigUri = Uri.withAppendedPath(ContentUris.withAppendedId(Contacts.CONTENT_URI,
64548e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov                queryContactId(rawContactId)), Contacts.Photo.CONTENT_DIRECTORY);
64558e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
64568e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
64578e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
64588e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
64598e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.putNull(Photo.PHOTO);
64608e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        Uri dataUri = mResolver.insert(Data.CONTENT_URI, values);
64618e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        long photoId = ContentUris.parseId(dataUri);
64628e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
6463155accbcb95fc13b984cf0ea8e5498a9c619cbf5Dmitri Plotnikov        assertEquals(0, getCount(twigUri, null, null));
64648e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
64658e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.clear();
64668e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        values.put(Photo.PHOTO, loadTestPhoto());
64678e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        mResolver.update(dataUri, values, null, null);
646881d6a78dffd57f24f9aaecb6cd54e4084c3c9846Dmitri Plotnikov        assertNetworkNotified(true);
64698e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
6470f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long twigId = getStoredLongValue(twigUri, Data._ID);
64718e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov        assertEquals(photoId, twigId);
64728e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov    }
64738e45e5f2142db78941b095f7418cc05b71668094Dmitri Plotnikov
64744e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactDataPhoto() {
64757d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a contact with a null photo
64767d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        ContentValues values = new ContentValues();
64777d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
64787d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        long rawContactId = ContentUris.parseId(rawContactUri);
64797d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
64807d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // setup a photo
64817d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.RAW_CONTACT_ID, rawContactId);
64827d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
64837d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.putNull(Photo.PHOTO);
64847d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
64857d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // try to do an update before insert should return count == 0
64867d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        Uri dataUri = Uri.withAppendedPath(
64877d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
64887d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                RawContacts.Data.CONTENT_DIRECTORY);
64897d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(0, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
64907d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
64917d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
64927d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        mResolver.insert(Data.CONTENT_URI, values);
64937d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
64947d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // save a photo to the db
64957d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.clear();
64967d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
64977d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        values.put(Photo.PHOTO, loadTestPhoto());
64987d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        assertEquals(1, mResolver.update(dataUri, values, Data.MIMETYPE + "=?",
64997d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                new String[] {Photo.CONTENT_ITEM_TYPE}));
65007d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
65017d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh        // verify the photo
65024e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Cursor storedPhoto = mResolver.query(dataUri, new String[] {Photo.PHOTO},
65037d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh                Data.MIMETYPE + "=?", new String[] {Photo.CONTENT_ITEM_TYPE}, null);
65044e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        storedPhoto.moveToFirst();
6505f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        MoreAsserts.assertEquals(loadTestPhoto(PhotoSize.THUMBNAIL), storedPhoto.getBlob(0));
65060265a180cf027d149f11f8750652ac67ea08ca24Dmitri Plotnikov        storedPhoto.close();
65077d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh    }
65087d9fdcf8346f789436148eff1f00e8f49b370ef0Neel Parekh
6509f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactId() throws IOException {
65108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6511f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6512f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6513f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_URI.buildUpon()
6514f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
6515f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
651687426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6517f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6518f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6519f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6520f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6521f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKey() throws IOException {
65228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6523f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6524f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
6525f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6526f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
6527f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
6528f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
652987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6530f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6531f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6532f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6533f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6534f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForContactLookupKeyAndId() throws IOException {
65358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6536f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6537f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String lookupKey = queryLookupKey(contactId);
6538f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6539f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = Contacts.CONTENT_LOOKUP_URI.buildUpon()
6540f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(lookupKey)
6541f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(contactId))
6542f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(Contacts.Photo.DISPLAY_PHOTO).build();
654387426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6544f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6545f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6546f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6547f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6548f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoForRawContactId() throws IOException {
65498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6550f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6551f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri photoUri = RawContacts.CONTENT_URI.buildUpon()
6552f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6553f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
655487426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6555f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6556f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(photoUri));
6557f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6558f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6559f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOpenDisplayPhotoByPhotoUri() throws IOException {
65608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6561f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6562f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_normal);
6563f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6564f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Get the photo URI out and check the content.
6565f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6566f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6567f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
656887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6569f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.DISPLAY_PHOTO),
6570f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6571f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6572f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6573f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForDisplayPhoto() {
65748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6575f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6576f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6577f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is larger than a thumbnail, so it will be stored as a file.
6578f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6579f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoFileId = getStoredValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6580f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Photo.PHOTO_FILE_ID);
6581f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6582f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6583f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6584f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6585f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI differs from the thumbnail.
6586f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6587f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6588f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6589f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoUri.equals(thumbnailUri));
6590f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6591f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form display_photo/ID
6592f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(DisplayPhoto.CONTENT_URI, photoFileId).toString(),
6593f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6594f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6595f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6596f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoUriForThumbnailPhoto() throws IOException {
65978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6598f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6599f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6600f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo being inserted is a thumbnail, so it will only be stored in a BLOB.  The photo URI
6601f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // will fall back to the thumbnail URI.
6602f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_small);
6603f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(
6604f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6605f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_URI);
6606f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6607f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the photo URI is equal to the thumbnail URI.
6608f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6609f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6610f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6611f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6612f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6613f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // URI should be of the form contacts/ID/photo
6614f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(Uri.withAppendedPath(
6615f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6616f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.Photo.CONTENT_DIRECTORY).toString(),
6617f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                photoUri);
6618f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6619f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Loading the photo URI content should get the thumbnail.
662087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6621f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6622f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6623f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6624f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6625c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteNewPhotoToAssetFile() throws Exception {
66268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6627f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6628f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6629f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6630c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final byte[] originalPhoto = loadPhotoFromResource(
6631c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL);
6632f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6633f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6634c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        final Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6635f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6636f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6637c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6638f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6639f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo and thumbnail have been set.
6640c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        String photoUri = null;
6641c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        for (int i = 0; i < 10 && photoUri == null; i++) {
6642c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            // Wait a tick for the photo processing to occur.
6643c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            Thread.sleep(100);
6644c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            photoUri = getStoredValue(
6645c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6646c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                Contacts.PHOTO_URI);
6647c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        }
6648c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6649f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(photoUri));
6650f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(
6651f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6652f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
6653f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(TextUtils.isEmpty(thumbnailUri));
6654c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        assertNotSame(photoUri, thumbnailUri);
6655f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6656f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
665787426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6658f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6659f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
666087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6661f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6662f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(thumbnailUri)));
6663f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6664f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6665c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    public void testWriteUpdatedPhotoToAssetFile() throws Exception {
66668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6667f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6668f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6669f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a large photo first.
6670f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        insertPhoto(rawContactId, R.drawable.earth_large);
6671f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String largeEarthPhotoUri = getStoredValue(
6672f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6673f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6674f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load in a huge photo.
6675f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] originalPhoto = loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL);
6676f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6677f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write it out.
6678f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri writeablePhotoUri = RawContacts.CONTENT_URI.buildUpon()
6679f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(String.valueOf(rawContactId))
6680f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                .appendPath(RawContacts.DisplayPhoto.CONTENT_DIRECTORY).build();
6681c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        writePhotoAsync(writeablePhotoUri, originalPhoto);
6682c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6683c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        // Allow a second for processing to occur.
6684c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        Thread.sleep(1000);
6685f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6686f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the display photo URI has been modified.
6687f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthPhotoUri = getStoredValue(
6688f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId), Contacts.PHOTO_URI);
6689f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(hugeEarthPhotoUri.equals(largeEarthPhotoUri));
6690f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6691f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check the content of the display photo and thumbnail.
6692f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String hugeEarthThumbnailUri = getStoredValue(
6693f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId),
6694f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_THUMBNAIL_URI);
669587426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6696f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.DISPLAY_PHOTO),
6697f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthPhotoUri)));
669887426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6699f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.THUMBNAIL),
6700f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(hugeEarthThumbnailUri)));
6701f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6702f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6703f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6704c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    private void writePhotoAsync(final Uri uri, final byte[] photoBytes) throws Exception {
6705c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
6706c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            @Override
6707c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            protected Object doInBackground(Object... params) {
6708c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                OutputStream os;
6709c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                try {
6710c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os = mResolver.openOutputStream(uri, "rw");
6711c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.write(photoBytes);
6712c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    os.close();
6713c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    return null;
6714c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                } catch (IOException ioe) {
6715c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                    throw new RuntimeException(ioe);
6716c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro                }
6717c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro            }
6718c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        };
6719c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null).get();
6720c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro    }
6721c6eab5080340824edd2c6676c4e6b96e142f87e4Dave Santoro
6722f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoDimensionLimits() {
6723f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6724f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.DISPLAY_MAX_DIM, 256);
6725f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DisplayPhoto.THUMBNAIL_MAX_DIM, 96);
6726f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertStoredValues(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI, values);
6727f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6728f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6729f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testPhotoStoreCleanup() throws IOException {
6730f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6731c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        PhotoStore photoStore = provider.getPhotoStore();
6732f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6733f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6734f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6735f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6736f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a couple of contacts with photos.
67378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
6738f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId1 = queryContactId(rawContactId1);
6739f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId1 = ContentUris.parseId(insertPhoto(rawContactId1, R.drawable.earth_normal));
6740f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId1 =
6741f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId1),
6742f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6743f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
67448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
6745f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId2 = queryContactId(rawContactId2);
6746f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId2 = ContentUris.parseId(insertPhoto(rawContactId2, R.drawable.earth_normal));
6747f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long photoFileId2 =
6748f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6749f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6750f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6751f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Update the second raw contact with a different photo.
6752f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues values = new ContentValues();
6753f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId2);
6754f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6755f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_huge, PhotoSize.ORIGINAL));
6756f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, mResolver.update(Data.CONTENT_URI, values, Data._ID + "=?",
6757f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                new String[]{String.valueOf(dataId2)}));
6758f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long replacementPhotoFileId =
6759f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId2),
6760f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                        Photo.PHOTO_FILE_ID);
6761f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6762f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Insert a third raw contact that has a bogus photo file ID.
6763f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusFileId = 1234567;
67648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId3 = RawContactUtil.createRawContactWithName(mResolver);
6765f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId3 = queryContactId(rawContactId3);
6766f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.clear();
6767f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.RAW_CONTACT_ID, rawContactId3);
6768f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
6769f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_normal,
6770f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoSize.THUMBNAIL));
6771f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(Photo.PHOTO_FILE_ID, bogusFileId);
6772f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        values.put(DataRowHandlerForPhoto.SKIP_PROCESSING_KEY, true);
6773f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.insert(Data.CONTENT_URI, values);
6774f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6775c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // Insert a fourth raw contact with a stream item that has a photo, then remove that photo
6776c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // from the photo store.
6777c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Account socialAccount = new Account("social", "social");
67788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId4 = RawContactUtil.createRawContactWithName(mResolver, socialAccount);
6779c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemUri =
6780c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                insertStreamItem(rawContactId4, buildGenericStreamItemValues(), socialAccount);
6781c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6782c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6783c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6784c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6785c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6786c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        photoStore.remove(streamItemPhotoFileId);
6787c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6788f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Also insert a bogus photo that nobody is using.
6789f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long bogusPhotoId = photoStore.insert(new PhotoProcessor(loadPhotoFromResource(
6790f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_huge, PhotoSize.ORIGINAL), 256, 96));
6791f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6792f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Manually trigger another cleanup in the provider.
6793f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        provider.cleanupPhotoStore();
6794f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6795f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The following things should have happened.
6796f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6797f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 1. Raw contact 1 and its photo remain unaffected.
6798f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoFileId1, (long) getStoredLongValue(
6799f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1),
6800f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6801f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6802f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 2. Raw contact 2 retains its new photo.  The old one is deleted from the photo store.
6803f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(replacementPhotoFileId, (long) getStoredLongValue(
6804f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2),
6805f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6806f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(photoFileId2));
6807f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6808f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 3. Raw contact 3 should have its photo file reference cleared.
6809f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(
6810f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId3),
6811f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                Contacts.PHOTO_FILE_ID));
6812f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6813f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // 4. The bogus photo that nobody was using should be cleared from the photo store.
6814f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(photoStore.get(bogusPhotoId));
6815c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro
6816c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        // 5. The bogus stream item photo should be cleared from the stream item.
6817c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6818c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6819c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6820c2714bbd397b09a20da476c89560e1caecdcce58Dave Santoro                new ContentValues[0]);
6821f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6822f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6823d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    public void testPhotoStoreCleanupForProfile() {
6824d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        SynchronousContactsProvider2 provider = (SynchronousContactsProvider2) mActor.provider;
6825d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        PhotoStore profilePhotoStore = provider.getProfilePhotoStore();
6826d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6827d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Trigger an initial cleanup so another one won't happen while we're running this test.
6828ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6829d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6830d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6831d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Create the profile contact and add a photo.
6832d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Account socialAccount = new Account("social", "social");
6833d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        ContentValues values = new ContentValues();
6834d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_NAME, socialAccount.name);
6835d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        values.put(RawContacts.ACCOUNT_TYPE, socialAccount.type);
6836d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileRawContactId = createBasicProfileContact(values);
6837d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profileContactId = queryContactId(profileRawContactId);
6838d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long dataId = ContentUris.parseId(
6839d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertPhoto(profileRawContactId, R.drawable.earth_normal));
6840d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long profilePhotoFileId =
6841d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                getStoredLongValue(ContentUris.withAppendedId(Data.CONTENT_URI, dataId),
6842d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        Photo.PHOTO_FILE_ID);
6843d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6844d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Also add a stream item with a photo.
6845d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemUri =
6846d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                insertStreamItem(profileRawContactId, buildGenericStreamItemValues(),
6847d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                        socialAccount);
6848d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemId = ContentUris.parseId(streamItemUri);
6849d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        Uri streamItemPhotoUri = insertStreamItemPhoto(
6850d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                streamItemId, buildGenericStreamItemPhotoValues(0), socialAccount);
6851d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        long streamItemPhotoFileId = getStoredLongValue(streamItemPhotoUri,
6852d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItemPhotos.PHOTO_FILE_ID);
6853d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6854d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Remove the stream item photo and the profile photo.
6855d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(profilePhotoFileId);
6856d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        profilePhotoStore.remove(streamItemPhotoFileId);
6857d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6858d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // Manually trigger another cleanup in the provider.
6859ae32283e7fc5b749df96523d8bb343b9068b65baMakoto Onuki        provider.switchToProfileModeForTest();
6860d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        provider.cleanupPhotoStore();
6861d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6862d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The following things should have happened.
6863d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6864d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The stream item photo should have been removed.
6865d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertStoredValues(Uri.withAppendedPath(
6866d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId),
6867d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                StreamItems.StreamItemPhotos.CONTENT_DIRECTORY),
6868d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                new ContentValues[0]);
6869d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6870d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        // The profile photo should have been cleared.
6871d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro        assertNull(getStoredValue(
6872d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                ContentUris.withAppendedId(Contacts.CONTENT_URI, profileContactId),
6873d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro                Contacts.PHOTO_FILE_ID));
6874d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6875d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro    }
6876d9125effce84804631c8e618ae88b2cfc69cf529Dave Santoro
6877f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testOverwritePhotoWithThumbnail() throws IOException {
68788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
6879f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long contactId = queryContactId(rawContactId);
6880f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
6881f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6882f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Write a regular-size photo.
6883f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long dataId = ContentUris.parseId(insertPhoto(rawContactId, R.drawable.earth_normal));
6884f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Long photoFileId = getStoredLongValue(contactUri, Contacts.PHOTO_FILE_ID);
6885f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != null && photoFileId > 0);
6886f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6887f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Now overwrite the photo with a thumbnail-sized photo.
6888f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        ContentValues update = new ContentValues();
6889f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        update.put(Photo.PHOTO, loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL));
6890f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mResolver.update(ContentUris.withAppendedId(Data.CONTENT_URI, dataId), update, null, null);
6891f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6892f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Photo file ID should have been nulled out, and the photo URI should be the same as the
6893f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // thumbnail URI.
6894f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(getStoredValue(contactUri, Contacts.PHOTO_FILE_ID));
6895f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String photoUri = getStoredValue(contactUri, Contacts.PHOTO_URI);
6896f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        String thumbnailUri = getStoredValue(contactUri, Contacts.PHOTO_THUMBNAIL_URI);
6897f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(photoUri, thumbnailUri);
6898f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
6899f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Retrieving the photo URI should get the thumbnail content.
690087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
6901c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki                loadPhotoFromResource(R.drawable.earth_small, PhotoSize.THUMBNAIL),
6902f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                mResolver.openInputStream(Uri.parse(photoUri)));
6903f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
6904f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
69054e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    public void testUpdateRawContactSetStarred() {
69068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContactWithName(mResolver);
69074e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
69088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContactWithName(mResolver);
69094e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
691047fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov        setAggregationException(
691147fd3881dfd2a21de29e917b6114974ff0a67b1bDmitri Plotnikov                AggregationExceptions.TYPE_KEEP_TOGETHER, rawContactId1, rawContactId2);
69124e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69134e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        long contactId = queryContactId(rawContactId1);
69144e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
69154e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
69164e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69174e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        ContentValues values = new ContentValues();
69184e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "1");
69194e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69204e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
69214e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69224e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
69234e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
69244e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
69254e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69264e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(RawContacts.STARRED, "0");
69274e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(rawContactUri1, values, null, null);
69284e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69294e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "0");
69304e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "0");
69314e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "0");
69324e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69334e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        values.put(Contacts.STARRED, "1");
69344e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        mResolver.update(contactUri, values, null, null);
69354e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69364e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.STARRED, "1");
69374e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.STARRED, "1");
69384e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov        assertStoredValue(contactUri, Contacts.STARRED, "1");
69394e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov    }
69404e8ced99f8bbb01abd610a6ca60afcabb6ffe737Dmitri Plotnikov
69416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testSetAndClearSuperPrimaryEmail() {
69428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
69436dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri11 = insertEmail(rawContactId1, "test1@domain1.com");
69446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri12 = insertEmail(rawContactId1, "test2@domain1.com");
69456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver, new Account("b", "b"));
69476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri21 = insertEmail(rawContactId2, "test1@domain2.com");
69486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri22 = insertEmail(rawContactId2, "test2@domain2.com");
69496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
69516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
69526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
69536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
69546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
69556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
69566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 0);
69576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
69586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Set super primary on the first pair, primary on the second
69606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
69616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
69626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
69636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
69646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
69656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
69666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
69676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
69686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
69696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
69706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 1);
69726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 1);
69736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
69746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
69756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
69766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
69776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
69786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
69796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Clear primary on the first pair, make sure second is not affected and super_primary is
69816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // also cleared
69826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
69836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
69846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
69856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri11, values, null, null);
69866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
69876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
69896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
69906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
69916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
69926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
69936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
69946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
69956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
69966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
69976dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear super_primary, if we specify the correct data row
69986dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
69996dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
70006dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
70016dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
70026dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
70036dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70046dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
70056dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
70066dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
70076dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
70086dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70096dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that we can only clear primary, if we specify the correct data row
70106dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
70116dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
70126dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 0);
70136dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri21, values, null, null);
70146dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
70156dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70166dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
70176dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
70186dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
70196dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 1);
70206dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70216dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Now clear super-primary for real
70226dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        {
70236dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            ContentValues values = new ContentValues();
70246dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 0);
70256dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri22, values, null, null);
70266dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
70276dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70286dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_PRIMARY, 0);
70296dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri11, Data.IS_SUPER_PRIMARY, 0);
70306dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_PRIMARY, 0);
70316dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri12, Data.IS_SUPER_PRIMARY, 0);
70326dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_PRIMARY, 0);
70336dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri21, Data.IS_SUPER_PRIMARY, 0);
70346dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_PRIMARY, 1);
70356dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri22, Data.IS_SUPER_PRIMARY, 0);
70366dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70376dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70386dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    /**
70396dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * Common function for the testNewPrimaryIn* functions. Its four configurations
70406dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     * are each called from its own test
70416dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann     */
70426dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testChangingPrimary(boolean inUpdate, boolean withSuperPrimary) {
70438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver, new Account("a", "a"));
70446dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        Uri mailUri1 = insertEmail(rawContactId, "test1@domain1.com", true);
70456dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70466dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (withSuperPrimary) {
70476dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
70486dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_SUPER_PRIMARY, 1);
70496dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri1, values, null, null);
70506dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
70516dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70526dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
70536dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
70546dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70556dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Insert another item
70566dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        final Uri mailUri2;
70576dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        if (inUpdate) {
70586dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com");
70596dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70606dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_PRIMARY, 1);
70616dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
70626dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_PRIMARY, 0);
70636dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, 0);
70646dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70656dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            final ContentValues values = new ContentValues();
70666dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            values.put(Data.IS_PRIMARY, 1);
70676dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mResolver.update(mailUri2, values, null, null);
70686dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        } else {
70696dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            // directly add as default
70706dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann            mailUri2 = insertEmail(rawContactId, "test2@domain1.com", true);
70716dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        }
70726dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70736dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // Ensure that primary has been unset on the first
70746dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        // If withSuperPrimary is set, also ensure that is has been moved to the new item
70756dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_PRIMARY, 0);
70766dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri1, Data.IS_SUPER_PRIMARY, 0);
70776dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_PRIMARY, 1);
70786dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        assertStoredValue(mailUri2, Data.IS_SUPER_PRIMARY, withSuperPrimary ? 1 : 0);
70796dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70806dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70816dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsert() {
70826dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, false);
70836dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70846dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70856dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInInsertWithSuperPrimary() {
70866dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(false, true);
70876dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70886dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70896dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdate() {
70906dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, false);
70916dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70926dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
70936dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    public void testNewPrimaryInUpdateWithSuperPrimary() {
70946dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann        testChangingPrimary(true, true);
70956dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann    }
70966dd371aea88e09cbe56b8c483021f3bf61527331Daniel Lehmann
7097a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    public void testContactSortOrder() {
7098a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + ", "
7099a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY,
7100a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY));
7101a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + ", "
7102a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_ALTERNATIVE,
7103a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE));
7104a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_PRIMARY + " DESC, "
7105a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + Contacts.SORT_KEY_PRIMARY + " DESC",
7106a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_PRIMARY + " DESC"));
7107a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        String suffix = " COLLATE LOCALIZED DESC";
7108a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        assertEquals(ContactsColumns.PHONEBOOK_BUCKET_ALTERNATIVE + suffix
7109a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     + ", " + Contacts.SORT_KEY_ALTERNATIVE + suffix,
7110a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                     ContactsProvider2.getLocalizedSortOrder(Contacts.SORT_KEY_ALTERNATIVE
7111a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                                                             + suffix));
7112a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
7113a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
7114ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    public void testContactCounts() {
7115ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Uri uri = Contacts.CONTENT_URI.buildUpon()
71161c6905d2f799d81d5cb847c44fca7dc7d36fd684Yorke Lee                .appendQueryParameter(Contacts.EXTRA_ADDRESS_BOOK_INDEX, "true").build();
7117ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
71188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContact(mResolver);
71198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "James", "Sullivan");
71208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "The Abominable", "Snowman");
71218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mike", "Wazowski");
71228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "randall", "boggs");
71238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Boo", null);
71248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Mary", null);
71258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.createRawContactWithName(mResolver, "Roz", null);
7126ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
7127ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        Cursor cursor = mResolver.query(uri,
7128ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
7129a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                null, null, Contacts.SORT_KEY_PRIMARY);
7130ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
713135997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "", "B", "J", "M", "R", "T");
7132ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,    1,   1,   1,   2,   2,   1);
7133ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
7134ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
7135ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor = mResolver.query(uri,
7136ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                new String[]{Contacts.DISPLAY_NAME},
7137ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov                null, null, Contacts.SORT_KEY_ALTERNATIVE + " COLLATE LOCALIZED DESC");
7138ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
713935997f3fdee2984b6d5373326110eda26929001aMakoto Onuki        assertFirstLetterValues(cursor, "W", "S", "R", "M", "B", "");
7140ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        assertFirstLetterCounts(cursor,   1,   2,   1,   1,   2,    1);
7141ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        cursor.close();
7142ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
7143ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
7144ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterValues(Cursor cursor, String... expected) {
7145ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        String[] actual = cursor.getExtras()
71467f4ce37bd099d8dbad3177a2b9ebe341811a5ce2Yorke Lee                .getStringArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_TITLES);
7147ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
7148ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
7149ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
7150ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    private void assertFirstLetterCounts(Cursor cursor, int... expected) {
7151ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        int[] actual = cursor.getExtras()
71527f4ce37bd099d8dbad3177a2b9ebe341811a5ce2Yorke Lee                .getIntArray(Contacts.EXTRA_ADDRESS_BOOK_INDEX_COUNTS);
7153ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov        MoreAsserts.assertEquals(expected, actual);
7154ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov    }
7155ba2c85b4700fbb3ecaf75e1101735f60b5483527Dmitri Plotnikov
7156f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testReadBooleanQueryParameter() {
7157f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", true, true);
7158f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar", "bool", false, false);
7159f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=0", "bool", true, false);
7160f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1", "bool", false, true);
7161f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false", "bool", true, false);
7162f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=true", "bool", false, true);
7163f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=FaLsE", "bool", true, false);
7164f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=false&some=some", "bool", true, false);
7165f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool=1&some=some", "bool", false, true);
7166f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?some=bool", "bool", true, true);
7167f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertBooleanUriParameter("foo:bar?bool", "bool", true, true);
7168f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
7169f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
7170f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertBooleanUriParameter(String uriString, String parameter,
7171f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov            boolean defaultValue, boolean expectedValue) {
7172f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.readBooleanQueryParameter(
7173f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter, defaultValue));
7174f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
7175f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
7176f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    public void testGetQueryParameter() {
7177f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar", "param", null);
7178f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param", "param", null);
7179f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=", "param", "");
7180f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val", "param", "val");
7181f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=val&some=some", "param", "val");
7182f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val", "param", "val");
7183f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?some=some&param=val&else=else", "param", "val");
7184f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertQueryParameter("foo:bar?param=john%40doe.com", "param", "john@doe.com");
71855fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val", "param", null);
71865fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2", "param", "val2");
71875fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=", "param", "");
71885fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param", "param", null);
71895fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&another_param=val2&param=val3",
71905fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val3");
71915fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?some_param=val1&param=val2&some_param=val3",
71925fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa                "param", "val2");
71935fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?param=val1&some_param=val2", "param", "val1");
71945fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?p=val1&pp=val2", "p", "val1");
71955fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?pp=val1&p=val2", "p", "val2");
71965fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val1&pp=val2&p=val3", "p", "val3");
71975fdc17bae46504edebe7285c3dbc7691ef3fbeb9Daisuke Miyakawa        assertQueryParameter("foo:bar?ppp=val&", "p", null);
7198f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
7199f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
7200e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testMissingAccountTypeParameter() {
7201e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try querying for RawContacts only using ACCOUNT_NAME
7202e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Uri queryUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(
7203e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey                RawContacts.ACCOUNT_NAME, "lolwut").build();
7204e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
7205e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            final Cursor cursor = mResolver.query(queryUri, null, null, null, null);
7206e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to query with incomplete account query parameters");
7207e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
7208e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
7209e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
7210e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
7211e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
7212e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    public void testInsertInconsistentAccountType() {
7213e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        // Try inserting RawContact with inconsistent Accounts
7214e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account red = new Account("red", "red");
7215e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final Account blue = new Account("blue", "blue");
7216e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
7217e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        final ContentValues values = new ContentValues();
7218e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_NAME, red.name);
7219e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        values.put(RawContacts.ACCOUNT_TYPE, red.type);
7220e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
72218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri insertUri = TestUtil.maybeAddAccountQueryParameters(RawContacts.CONTENT_URI,
72228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                blue);
7223e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        try {
7224e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            mResolver.insert(insertUri, values);
7225e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            fail("Able to insert RawContact with inconsistent account details");
7226e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        } catch (IllegalArgumentException e) {
7227e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey            // Expected behavior.
7228e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey        }
7229e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey    }
7230e246689441b2ff39cb97de277d6caeec95358863Jeff Sharkey
72313826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusNoContactsNoAccounts() throws Exception {
72323826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
72333826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
72343826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
72353826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusOnlyLocalContacts() throws Exception {
72368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
72373826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
72383826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        mResolver.delete(
72393826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov                ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), null, null);
72403826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
72413826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
72423826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
72433826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    public void testProviderStatusWithAccounts() throws Exception {
72443826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
72458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        mActor.setAccounts(new Account[]{TestUtil.ACCOUNT_1});
72468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[]{TestUtil.ACCOUNT_1});
72473826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NORMAL);
7248bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov        mActor.setAccounts(new Account[0]);
72493826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        ((ContactsProvider2)getProvider()).onAccountsUpdated(new Account[0]);
72503826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertProviderStatus(ProviderStatus.STATUS_NO_ACCOUNTS_NO_CONTACTS);
72513826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    }
72523826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov
72533826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov    private void assertProviderStatus(int expectedProviderStatus) {
725409c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI,
725509c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov                new String[]{ProviderStatus.DATA1, ProviderStatus.STATUS}, null, null, null);
725609c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertTrue(cursor.moveToFirst());
725709c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        assertEquals(0, cursor.getLong(0));
72583826a44d8de41e9c148dd6a967392ea5af478085Dmitri Plotnikov        assertEquals(expectedProviderStatus, cursor.getInt(1));
725909c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov        cursor.close();
726009c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov    }
726109c6613dd14cb1911da5d62e39a4e54eb8f4666fDmitri Plotnikov
7262b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    public void testProperties() throws Exception {
7263743eac356404195f236ad44379fe9d180beb5bf2Dmitri Plotnikov        ContactsProvider2 provider = (ContactsProvider2)getProvider();
7264b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        ContactsDatabaseHelper helper = (ContactsDatabaseHelper)provider.getDatabaseHelper();
7265b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertNull(helper.getProperty("non-existent", null));
7266b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("non-existent", "default"));
7267b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
7268b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", "string1");
7269b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent2", "string2");
7270b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string1", helper.getProperty("existent1", "default"));
7271b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("string2", helper.getProperty("existent2", "default"));
7272b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        helper.setProperty("existent1", null);
7273b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov        assertEquals("default", helper.getProperty("existent1", "default"));
7274b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov    }
7275b2e27298ae54ec2215eadf98ecc100aedba98d1aDmitri Plotnikov
727642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private class VCardTestUriCreator {
727742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup1;
727842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        private String mLookup2;
727942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
728042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public VCardTestUriCreator(String lookup1, String lookup2) {
728142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            super();
728242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup1 = lookup1;
728342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mLookup2 = lookup2;
728442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
728542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
728642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri1() {
728742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup1);
728842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
728942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
729042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getUri2() {
729142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_VCARD_URI, mLookup2);
729242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
729342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
729442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        public Uri getCombinedUri() {
729542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
729642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                    Uri.encode(mLookup1 + ":" + mLookup2));
729742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
729842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
729942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
730042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private VCardTestUriCreator createVCardTestContacts() {
73018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId1 = RawContactUtil.createRawContact(mResolver, mAccount,
73028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "4:12");
73038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId1, "John", "Doe");
730442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
73058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rawContactId2 = RawContactUtil.createRawContact(mResolver, mAccount,
73068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                RawContacts.SOURCE_ID, "3:4%121");
73078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId2, "Jane", "Doh");
730842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
730942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId1 = queryContactId(rawContactId1);
731042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final long contactId2 = queryContactId(rawContactId2);
731142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact1Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId1);
731242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final Uri contact2Uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId2);
731342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup1 =
731442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact1Uri).getPathSegments().get(2));
731542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final String lookup2 =
731642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Uri.encode(Contacts.getLookupUri(mResolver, contact2Uri).getPathSegments().get(2));
731742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        return new VCardTestUriCreator(lookup1, lookup2);
731842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
731942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
732042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryMultiVCard() {
732142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // No need to create any contacts here, because the query for multiple vcards
732242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // does not go into the database at all
732342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI, Uri.encode("123:456"));
732442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        Cursor cursor = mResolver.query(uri, null, null, null, null);
732542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertEquals(1, cursor.getCount());
732642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.moveToFirst());
732742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
732842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
732942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
733042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // The resulting name contains date and time. Ensure that before and after are correct
733142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.startsWith("vcards_"));
733242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(filename.endsWith(".vcf"));
733342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        cursor.close();
733442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
733542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
733642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testQueryFileSingleVCard() {
733742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
733842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
733942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
734042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri1(), null, null, null, null);
734142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
734242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
734342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
734442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
734542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("John Doe.vcf", filename);
734642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
734742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
734842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
734942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
735042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            Cursor cursor = mResolver.query(contacts.getUri2(), null, null, null, null);
735142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals(1, cursor.getCount());
735242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.moveToFirst());
735342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
735442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
735542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertEquals("Jane Doh.vcf", filename);
735642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            cursor.close();
735742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
735842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
735942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
736024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    public void testQueryFileProfileVCard() {
736124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        createBasicProfileContact(new ContentValues());
736224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Cursor cursor = mResolver.query(Profile.CONTENT_VCARD_URI, null, null, null, null);
736324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals(1, cursor.getCount());
736424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.moveToFirst());
736524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertTrue(cursor.isNull(cursor.getColumnIndex(OpenableColumns.SIZE)));
736624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        String filename = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
736724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        assertEquals("Mia Prophyl.vcf", filename);
736824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        cursor.close();
736924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
737042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
737142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileMultiVCard() throws IOException {
737242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
737342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
737442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final AssetFileDescriptor descriptor =
737542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            mResolver.openAssetFileDescriptor(contacts.getCombinedUri(), "r");
737642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final FileInputStream inputStream = descriptor.createInputStream();
737742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        String data = readToEnd(inputStream);
737842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        inputStream.close();
737942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        descriptor.close();
738042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
738142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the resulting VCard has both contacts
738242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doe;John;;;"));
738342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        assertTrue(data.contains("N:Doh;Jane;;;"));
738442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
738542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
738642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    public void testOpenAssetFileSingleVCard() throws IOException {
738742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        final VCardTestUriCreator contacts = createVCardTestContacts();
738842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
738942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        // Ensure that the right VCard is being created in each case
739042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
739142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
739242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri1(), "r");
739342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
739442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
739542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
739642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
739724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
739824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertTrue(data.contains("N:Doe;John;;;"));
739924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            assertFalse(data.contains("N:Doh;Jane;;;"));
740042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
740142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
740242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        {
740342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final AssetFileDescriptor descriptor =
740442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                mResolver.openAssetFileDescriptor(contacts.getUri2(), "r");
740542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final FileInputStream inputStream = descriptor.createInputStream();
740642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            final String data = readToEnd(inputStream);
740742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            inputStream.close();
740842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            descriptor.close();
740942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
741042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertFalse(data.contains("N:Doe;John;;;"));
741142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            assertTrue(data.contains("N:Doh;Jane;;;"));
741242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
741342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
741442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
7415dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testAutoGroupMembership() {
7416dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
7417dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
7418dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false /* favorite */);
7419dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, false/* favorite */);
74208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
74218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
74228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, null);
7423dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7424dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7425dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7426dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7427dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7428dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7429dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7430dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7431dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7432dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7433dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7434dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
7435dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7436dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7437dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g3, c.getLong(0));
7438dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r2, c.getLong(1));
7439dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7440dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7441dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7442dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7443dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7444dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7445dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testNoAutoAddMembershipAfterGroupCreation() {
74468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
74478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
74488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount);
74498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
74508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
74518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null);
7452dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7453dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7454dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7455dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7456dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, true /* autoAdd */, false /* favorite */);
7457dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
7458dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, true /* autoAdd */, false/* favorite */);
7459dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7460dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7461dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7462dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7463dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7464dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // create some starred and non-starred contacts, some associated with account, some not
7465dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group created
7466dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // the starred contacts should be added to group
7467dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // favorites group removed
7468dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    // no change to starred status
7469dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesMembershipAfterGroupCreation() {
74708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
74718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
74728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
74738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r4 = RawContactUtil.createRawContact(mResolver, mAccountTwo, RawContacts.STARRED, "1");
74748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r5 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
74758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r6 = RawContactUtil.createRawContact(mResolver, null, RawContacts.STARRED, "1");
74768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r7 = RawContactUtil.createRawContact(mResolver, null);
7477dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7478dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7479dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7480dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7481dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7482dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false /* favorite */);
7483dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g3 = createGroup(mAccountTwo, "g3", "t3", 0, false /* autoAdd */, false/* favorite */);
7484dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7485dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7486dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7487dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7488dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
7489dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
7490dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
7491dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
7492dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7493dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7494dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7495dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7496dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7497dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7498dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7499dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7500dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7501dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7502dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7503dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7504dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7505dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7506dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7507dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(RawContacts.CONTENT_URI, r6,
7508dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_NAME, mAccount.name,
7509dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                RawContacts.ACCOUNT_TYPE, mAccount.type);
7510dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7511dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7512dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7513dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7514dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7515dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7516dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7517dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7518dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7519dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7520dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7521dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r6, c.getLong(1));
7522dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7523dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7524dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7525dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7526dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7527dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(ContentUris.withAppendedId(Groups.CONTENT_URI, g1), null, null);
7528dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7529dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7530dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7531dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7532dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7533dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7534dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7535dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r4));
7536dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r5));
7537dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r6));
7538dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r7));
7539dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7540dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7541dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testFavoritesGroupMembershipChangeAfterStarChange() {
7542dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7543dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7544dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7545dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
75468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount, RawContacts.STARRED, "1");
75478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
75488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7549dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7550dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7551dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c = queryGroupMemberships(mAccount);
7552dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7553dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7554dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7555dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7556dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7557dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7558dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7559dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7560dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7561dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7562dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7563dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7564dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7565dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7566dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7567dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7568dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred
7569dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "1"));
7570dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7571dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7572dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7573dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7574dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7575dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7576dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7577dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7578dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7579dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7580dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7581dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7582dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7583dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7584dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7585dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(RawContacts.CONTENT_URI, r1, RawContacts.STARRED, "0"));
7586dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7587dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7588dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7589dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7590e3e79030101447da07547647bad225686eb9b8dfDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, queryContactId(r1));
7591dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNotNull(contactUri);
7592dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7593dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // mark r1 as starred via its contact lookup uri
7594dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertEquals(1, updateItem(contactUri, Contacts.STARRED, "1"));
7595dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Now that r1 is starred it should have a membership in the one groups from mAccount
7596dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // that is marked as a favorite.
7597dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // There should be no memberships in mAccountTwo since it has no starred raw contacts.
7598dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7599dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7600dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7601dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7602dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7603dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7604dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7605dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7606dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7607dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7608dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7609dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove the star from r1
7610dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        updateItem(contactUri, Contacts.STARRED, "0");
7611dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // Since no raw contacts are starred, there should be no group memberships.
7612dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7613dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7614dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7615dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7616dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    public void testStarChangedAfterGroupMembershipChange() {
7617dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g1 = createGroup(mAccount, "g1", "t1", 0, false /* autoAdd */, true /* favorite */);
7618dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g2 = createGroup(mAccount, "g2", "t2", 0, false /* autoAdd */, false/* favorite */);
7619dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g4 = createGroup(mAccountTwo, "g4", "t4", 0, false /* autoAdd */, true /* favorite */);
7620dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        long g5 = createGroup(mAccountTwo, "g5", "t5", 0, false /* autoAdd */, false/* favorite */);
76218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r1 = RawContactUtil.createRawContact(mResolver, mAccount);
76228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r2 = RawContactUtil.createRawContact(mResolver, mAccount);
76238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long r3 = RawContactUtil.createRawContact(mResolver, mAccountTwo);
7624dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7625dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7626dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7627dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7628dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7629dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Cursor c;
7630dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7631dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r1 to one favorites group
7632dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should automatically be set
7633dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1 should automatically be added to the other favorites group
7634dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir1g1 = insertGroupMembership(r1, g1);
7635dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r1));
7636dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7637dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7638dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7639dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccount);
7640dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7641dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7642dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g1, c.getLong(0));
7643dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r1, c.getLong(1));
7644dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7645dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7646dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7647dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7648dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7649dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r1 from one favorites group
7650dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir1g1, null, null);
7651dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r1's star should no longer be set
7652dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7653dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7654dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7655dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // there should be no membership rows
7656dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7657dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7658dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7659dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // add r3 to the one favorites group for that account
7660dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be set
7661dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        Uri urir3g4 = insertGroupMembership(r3, g4);
7662dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7663dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7664dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertTrue(queryRawContactIsStarred(r3));
7665dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7666dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        c = queryGroupMemberships(mAccountTwo);
7667dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        try {
7668dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertTrue(c.moveToNext());
7669dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(g4, c.getLong(0));
7670dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertEquals(r3, c.getLong(1));
7671dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            assertFalse(c.moveToNext());
7672dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        } finally {
7673dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana            c.close();
7674dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        }
7675dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
7676dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // remove r3 from the favorites group
7677dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        mResolver.delete(urir3g4, null, null);
7678dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        // r3's star should automatically be cleared
7679dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r1));
7680dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r2));
7681dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertFalse(queryRawContactIsStarred(r3));
7682dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccount));
7683dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        assertNoRowsAndClose(queryGroupMemberships(mAccountTwo));
7684dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
7685dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
768697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyRawContact() {
76878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
768897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
768997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
769097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
769197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
769297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "second");
769397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "first");
769497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
769597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = rawContactUri.buildUpon()
769697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
769797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
769897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, RawContacts.CUSTOM_RINGTONE, "third");
769997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri, RawContacts.CUSTOM_RINGTONE, "third");
770097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
770197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
770297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testReadOnlyDataRow() {
77038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContact(mResolver);
770497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri emailUri = insertEmail(rawContactId, "email");
770597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri phoneUri = insertPhoneNumber(rawContactId, "555-1111");
770697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
770797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Data.IS_READ_ONLY, "1");
770897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(emailUri, Email.ADDRESS, "changed");
770997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(phoneUri, Phone.NUMBER, "555-2222");
771097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "email");
771197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(phoneUri, Phone.NUMBER, "555-2222");
771297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
771397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri syncAdapterUri = emailUri.buildUpon()
771497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "1")
771597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                .build();
771697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(syncAdapterUri, Email.ADDRESS, "changed");
771797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(emailUri, Email.ADDRESS, "changed");
771897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
771997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
772097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    public void testContactWithReadOnlyRawContact() {
77218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId1 = RawContactUtil.createRawContact(mResolver);
772297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri1 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId1);
772397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "first");
772497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
77258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId2 = RawContactUtil.createRawContact(mResolver);
772697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri rawContactUri2 = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId2);
772797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
772897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(rawContactUri2, RawContacts.RAW_CONTACT_IS_READ_ONLY, 1);
772997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
773097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER,
773197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov                rawContactId1, rawContactId2);
773297fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
773397fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        long contactId = queryContactId(rawContactId1);
773497fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
773597fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
773697fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        storeValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
773797fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(contactUri, Contacts.CUSTOM_RINGTONE, "rt");
773897fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri1, RawContacts.CUSTOM_RINGTONE, "rt");
773997fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov        assertStoredValue(rawContactUri2, RawContacts.CUSTOM_RINGTONE, "second");
774097fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov    }
774197fd30388bd6530f86679510cd7b43b9c518bcefDmitri Plotnikov
77427a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameParsingQuery() {
77437a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
77447a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.").build();
77457a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
77467a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
77477a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr. John Q. Doe Jr.");
774817a22fae02931ae536f35293ca13a8de53439f72Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr.");
77497a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
77507a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
77517a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
77527a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
77537a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
77547a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
77557a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
77567a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
77577a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
77587a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
77597a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    public void testNameConcatenationQuery() {
77607a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Uri uri = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name")
77617a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.PREFIX, "Mr")
77627a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.GIVEN_NAME, "John")
77637a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.MIDDLE_NAME, "Q.")
77647a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.FAMILY_NAME, "Doe")
77657a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .appendQueryParameter(StructuredName.SUFFIX, "Jr.")
77667a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov                .build();
77677a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        Cursor cursor = mResolver.query(uri, null, null, null, null);
77687a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        ContentValues values = new ContentValues();
776955e5cbf566edd89fc55f4a7f0ef2847084da9b16Dmitri Plotnikov        values.put(StructuredName.DISPLAY_NAME, "Mr John Q. Doe, Jr.");
77707a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.PREFIX, "Mr");
77717a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.GIVEN_NAME, "John");
77727a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.MIDDLE_NAME, "Q.");
77737a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FAMILY_NAME, "Doe");
77747a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.SUFFIX, "Jr.");
77757a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        values.put(StructuredName.FULL_NAME_STYLE, FullNameStyle.WESTERN);
77767a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertTrue(cursor.moveToFirst());
77777a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        assertCursorValues(cursor, values);
77787a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov        cursor.close();
77797a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov    }
77807a3c645fa7db38449d34eb04d4e032fd079c3244Dmitri Plotnikov
7781084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    public void testBuildSingleRowResult() {
7782084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7783084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b"},
7784084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7785084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7786084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2}
7787084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7788084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7789084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7790084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"b", "a", "b"},
7791084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7792084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7793084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {2, 1, 2}
7794084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7795084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7796084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        checkBuildSingleRowResult(
7797084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                null, // all columns
7798084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new String[] {"a", "b"},
7799084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2},
7800084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                new Integer[] {1, 2}
7801084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                );
7802084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7803084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7804084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            // Access non-existent column
7805084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            ContactsProvider2.buildSingleRowResult(new String[] {"a"}, new String[] {"b"},
7806084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                    new Object[] {1});
7807084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            fail();
7808084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } catch (IllegalArgumentException expected) {
7809084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7810084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7811084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7812084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    private void checkBuildSingleRowResult(String[] projection, String[] availableColumns,
7813084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            Object[] data, Integer[] expectedValues) {
7814084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        final Cursor c = ContactsProvider2.buildSingleRowResult(projection, availableColumns, data);
7815084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        try {
7816084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertTrue(c.moveToFirst());
7817084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(1, c.getCount());
7818084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            assertEquals(expectedValues.length, c.getColumnCount());
7819084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7820084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            for (int i = 0; i < expectedValues.length; i++) {
7821084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki                assertEquals("column " + i, expectedValues[i], (Integer) c.getInt(i));
7822084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            }
7823084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        } finally {
7824084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki            c.close();
7825084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki        }
7826084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki    }
7827084fe28445cf74e3fa93522f8f8e5da6e065b8c3Makoto Onuki
7828dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    public void testDataUsageFeedbackAndDelete() {
7829dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7830dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.install();
7831d820edb03bd5caffc0dff19096552efa817dec59Yorke Lee        sMockClock.setCurrentTimeMillis(System.currentTimeMillis());
7832dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long startTime = sMockClock.currentTimeMillis();
7833dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
78348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid1 = RawContactUtil.createRawContactWithName(mResolver, "contact", "a");
7835dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1a = ContentUris.parseId(insertEmail(rid1, "email_1_a@email.com"));
7836dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1b = ContentUris.parseId(insertEmail(rid1, "email_1_b@email.com"));
7837dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did1p = ContentUris.parseId(insertPhoneNumber(rid1, "555-555-5555"));
7838dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
78398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid2 = RawContactUtil.createRawContactWithName(mResolver, "contact", "b");
7840dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2a = ContentUris.parseId(insertEmail(rid2, "email_2_a@email.com"));
7841dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did2p = ContentUris.parseId(insertPhoneNumber(rid2, "555-555-5556"));
7842dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7843dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Aggregate 1 and 2
7844dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, rid1, rid2);
7845dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
78468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid3 = RawContactUtil.createRawContactWithName(mResolver, "contact", "c");
7847dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3a = ContentUris.parseId(insertEmail(rid3, "email_3@email.com"));
7848dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did3p = ContentUris.parseId(insertPhoneNumber(rid3, "555-3333"));
7849dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
78508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long rid4 = RawContactUtil.createRawContactWithName(mResolver, "contact", "d");
7851dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long did4p = ContentUris.parseId(insertPhoneNumber(rid4, "555-4444"));
7852dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7853dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid1 = queryContactId(rid1);
7854dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid3 = queryContactId(rid3);
7855dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final long cid4 = queryContactId(rid4);
7856dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7857dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Make sure 1+2, 3 and 4 aren't aggregated
7858dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid3);
7859dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid1, cid4);
7860dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(cid3, cid4);
7861dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7862dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime
7863dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7864a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // First, there's no frequent.  (We use strequent here only because frequent is hidden
7865a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // and may be removed someday.)
7866a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7867a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7868dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 1. touch data 1a
7869dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a);
7870a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7871dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, there's a single frequent.  (contact 1)
7872a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(1, Contacts.CONTENT_STREQUENT_URI, null, null);
7873a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7874dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 1
7875dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7876dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7877dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 1a, 2a and 3a
7878dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_LONG_TEXT, did1a, did2a, did3a);
7879dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7880dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Now, contact 1 and 3 are in frequent.
7881dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7882dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7883dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 2
7884dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7885dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7886dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 2. touch data 2p (call)
7887dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_CALL, did2p);
7888dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7889dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // There're still two frequent.
7890dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertRowCount(2, Contacts.CONTENT_STREQUENT_URI, null, null);
7891dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7892dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // time = startTime + 3
7893dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        sMockClock.advance();
7894dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7895dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Test 3. touch data 2p and 3p (short text)
7896dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        updateDataUsageFeedback(DataUsageFeedback.USAGE_TYPE_SHORT_TEXT, did2p, did3p);
7897dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7898dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's check the tables.
7899dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7900dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Fist, check the data_usage_stat table, which has no public URI.
7901dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7902dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.USAGE_TYPE_INT +
7903dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.TIMES_USED +
7904dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                "," + DataUsageStatColumns.LAST_TIME_USED +
7905dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7906dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did1a,
7907dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7908dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7909dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 2,
7910dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7911dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7912dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2a,
7913dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7914dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7915dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7916dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7917dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7918dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3a,
7919dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7920dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_LONG_TEXT,
7921dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7922dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 1
7923dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7924dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7925dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7926dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_CALL,
7927dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7928dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 2
7929dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7930dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did2p,
7931dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7932dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7933dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7934dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7935dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7936dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(DataUsageStatColumns.DATA_ID, did3p,
7937dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.USAGE_TYPE_INT,
7938dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                            DataUsageStatColumns.USAGE_TYPE_INT_SHORT_TEXT,
7939dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.TIMES_USED, 1,
7940dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        DataUsageStatColumns.LAST_TIME_USED, startTime + 3
7941dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7942dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7943dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7944dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Next, check the raw_contacts table
7945dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
7946dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid1,
7947dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7948dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 1
7949dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7950dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid2,
7951dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 3,
7952dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7953dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7954dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid3,
7955dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 2,
7956dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, startTime + 3
7957dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7958dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(RawContacts._ID, rid4,
7959dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.TIMES_CONTACTED, 0,
7960dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        RawContacts.LAST_TIME_CONTACTED, null // 4 wasn't touched.
7961dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7962dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7963dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7964dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Lastly, check the contacts table.
7965dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7966dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Note contact1.TIMES_CONTACTED = 4, even though raw_contact1.TIMES_CONTACTED +
7967dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // raw_contact1.TIMES_CONTACTED = 5, because in test 2, data 1a and data 2a were touched
7968dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // at once.
7969dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
7970dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid1,
7971dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 4,
7972dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7973dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7974dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid3,
7975dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 2,
7976dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, startTime + 3
7977dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        ),
7978dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                cv(Contacts._ID, cid4,
7979dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.TIMES_CONTACTED, 0,
7980dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        Contacts.LAST_TIME_CONTACTED, 0 // For contacts, the default is 0, not null.
7981dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                        )
7982dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                );
7983a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7984dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // Let's test the delete too.
7985b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
7986a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7987a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Now there's no frequent.
7988a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_STREQUENT_URI, null, null);
7989a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
7990dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        // No rows in the stats table.
7991dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        assertStoredValuesDb("SELECT " + DataUsageStatColumns.DATA_ID +
7992dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                " FROM " + Tables.DATA_USAGE_STAT, null,
7993dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                new ContentValues[0]);
7994dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
7995a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // The following values should all be 0 or null.
7996a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.TIMES_CONTACTED + ">0", null);
7997a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, Contacts.CONTENT_URI, Contacts.LAST_TIME_CONTACTED + ">0", null);
7998a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.TIMES_CONTACTED + ">0", null);
7999a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        assertRowCount(0, RawContacts.CONTENT_URI, RawContacts.LAST_TIME_CONTACTED + ">0", null);
8000a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
8001a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki        // Calling it when there's no usage stats will still return a positive value.
8002b6186821548995dce533ee502e82e9abf4c0aadcMakoto Onuki        assertTrue(mResolver.delete(DataUsageFeedback.DELETE_USAGE_URI, null, null) > 0);
8003a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki    }
8004a780048d2caafbd922444b0c08adb81790db4635Makoto Onuki
80058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /*******************************************************
80068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Delta api tests.
80078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
80088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_hasDeleteLog() {
80098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
80108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long start = sMockClock.currentTimeMillis();
80118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
80128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, start);
80138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up. Must also remove raw contact.
80158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
80168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactDelete_marksRawContactsForDeletion() {
80198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
80208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        String[] projection = new String[]{ContactsContract.RawContacts.DIRTY,
80228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.RawContacts.DELETED};
80238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        List<String[]> records = RawContactUtil.queryByContactId(mResolver, ids.mContactId,
80248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                projection);
80258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] arr : records) {
80268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[0]);
80278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertEquals("1", arr[1]);
80288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
80298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
80318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
80328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testContactUpdate_updatesContactUpdatedTimestamp() {
80358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
80368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
80378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
80418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.Contacts.STARRED, 1);
80428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
80448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.update(mResolver, ids.mContactId, values);
80458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
80488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
80508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
80518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    // This implicitly tests the Contact create case.
80548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactCreate_updatesContactUpdatedTimestamp() {
80558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long startTime = System.currentTimeMillis();
80568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long rawContactId = RawContactUtil.createRawContactWithName(mResolver);
80588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long lastUpdated = getContactLastUpdatedTimestampByRawContactId(mResolver, rawContactId);
80598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(lastUpdated > startTime);
80618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
80638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, rawContactId, true);
80648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactUpdate_updatesContactUpdatedTimestamp() {
80678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
80688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
80728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.RawContacts.STARRED, 1);
80738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.update(mResolver, ids.mRawContactId, values);
80748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
80778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
80798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
80808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactPsuedoDelete_hasDeleteLogForContact() {
80838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
80848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, false);
80888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
80908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // clean up
80928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
80938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
80948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testRawContactDelete_hasDeleteLogForContact() {
80968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
80978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
80988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
80998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
81018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertHasDeleteLogGreaterThan(mResolver, ids.mContactId, baseTime);
81038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // already clean
81058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long getContactLastUpdatedTimestampByRawContactId(ContentResolver resolver,
81088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            long rawContactId) {
81098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long contactId = RawContactUtil.queryContactIdByRawContactId(mResolver, rawContactId);
81108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND, contactId);
81118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
81138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataInsert_updatesContactLastUpdatedTimestamp() {
81168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
81178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
81188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
81218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        insertPhoneNumberAndReturnDataId(ids.mRawContactId);
81228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
81258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
81278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
81288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataDelete_updatesContactLastUpdatedTimestamp() {
81318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
81328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
81338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
81358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
81398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.delete(mResolver, dataId);
81408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
81438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
81458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
81468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDataUpdate_updatesContactLastUpdatedTimestamp() {
81498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
81508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
81518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long dataId = insertPhoneNumberAndReturnDataId(ids.mRawContactId);
81538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
81578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContentValues values = new ContentValues();
81588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, "555-5555");
81598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.update(mResolver, dataId, values);
81608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        long newTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, ids.mContactId);
81628ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertTrue(newTime > baseTime);
81638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Clean up
81658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        RawContactUtil.delete(mResolver, ids.mRawContactId, true);
81668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81678ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81688ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private long insertPhoneNumberAndReturnDataId(long rawContactId) {
81698ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = insertPhoneNumber(rawContactId, "1-800-GOOG-411");
81708ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ContentUris.parseId(uri);
81718ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81728ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81738ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsDelete_isUnsupported() {
81748ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
81758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, URI);
81768ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81778ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Uri uri = ContentUris.withAppendedId(URI, 1L);
81788ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertDeleteIsUnsupported(mResolver, uri);
81798ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81808ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81818ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testDeletedContactsInsert_isUnsupported() {
81828ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final Uri URI = ContactsContract.DeletedContacts.CONTENT_URI;
81838ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.assertInsertIsUnsupported(mResolver, URI);
81848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81858ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81868ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81878ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsByContactId() {
81888ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = assertContactCreateDelete();
81898ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81908ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        MoreAsserts.assertNotEqual(CommonDatabaseUtils.NOT_FOUND,
81918ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
81928ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
81938ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81948ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsAll() {
81958ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final int numDeletes = 10;
81968ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
81978ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Since we cannot clean out delete log from previous tests, we need to account for that
81988ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // by querying for the count first.
81998ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long startCount = DeletedContactUtil.getCount(mResolver);
82008ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82018ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (int i = 0; i < numDeletes; i++) {
82028ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertContactCreateDelete();
82038ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
82048ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82058ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long endCount = DeletedContactUtil.getCount(mResolver);
82068ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82078ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(numDeletes, endCount - startCount);
82088ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
82098ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82108ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    public void testQueryDeletedContactsSinceTimestamp() {
82118ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.install();
82128ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82138ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // Before
82148ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> beforeIds = new HashSet<Long>();
82158ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
82168ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        beforeIds.add(assertContactCreateDelete().mContactId);
82178ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82188ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final long start = sMockClock.currentTimeMillis();
82198ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        // After
82218ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final HashSet<Long> afterIds = new HashSet<Long>();
82228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
82238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
82248ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        afterIds.add(assertContactCreateDelete().mContactId);
82258ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82268ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final String[] projection = new String[]{
82278ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_ID,
82288ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                ContactsContract.DeletedContacts.CONTACT_DELETED_TIMESTAMP
82298ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        };
82308ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        final List<String[]> records = DeletedContactUtil.querySinceTimestamp(mResolver, projection,
82318ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                start);
82328ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        for (String[] record : records) {
82338ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check ids to make sure we only have the ones that came after the time.
82348ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            final long contactId = Long.parseLong(record[0]);
82358ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertFalse(beforeIds.contains(contactId));
82368ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(afterIds.contains(contactId));
82378ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82388ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            // Check times to make sure they came after
82398ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng            assertTrue(Long.parseLong(record[1]) > start);
82408ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        }
82418ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
82428ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82438ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
82448ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * Create a contact. Assert it's not present in the delete log. Delete it.
82458ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * And assert that the contact record is no longer present.
82468ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     *
82478ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * @return The contact id and raw contact id that was created.
82488ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     */
82498ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    private DatabaseAsserts.ContactIdPair assertContactCreateDelete() {
82508ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DatabaseAsserts.ContactIdPair ids = DatabaseAsserts.assertAndCreateContact(mResolver);
82518ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82528ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertEquals(CommonDatabaseUtils.NOT_FOUND,
82538ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                DeletedContactUtil.queryDeletedTimestampForContactId(mResolver, ids.mContactId));
82548ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82558ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        sMockClock.advance();
82568ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        ContactUtil.delete(mResolver, ids.mContactId);
82578ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82588ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        assertFalse(ContactUtil.recordExistsForContactId(mResolver, ids.mContactId));
82598ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
82608ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        return ids;
82618ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    }
826281fea08280784b319b936a3506788d595c6ce2adYorke Lee
82638ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng    /**
82648ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     * End delta api tests.
82658ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng     ******************************************************/
82668ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
826781fea08280784b319b936a3506788d595c6ce2adYorke Lee    /*******************************************************
826881fea08280784b319b936a3506788d595c6ce2adYorke Lee     * Pinning support tests
826981fea08280784b319b936a3506788d595c6ce2adYorke Lee     */
8270dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee    public void testPinnedPositionsUpdate() {
827181fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
827281fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
827381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
827481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
827581fea08280784b319b936a3506788d595c6ce2adYorke Lee
827681fea08280784b319b936a3506788d595c6ce2adYorke Lee        final int unpinned = PinnedPositions.UNPINNED;
827781fea08280784b319b936a3506788d595c6ce2adYorke Lee
827881fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
827981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
828081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
828181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
828281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0)
828381fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
828481fea08280784b319b936a3506788d595c6ce2adYorke Lee
828581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
828681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, unpinned),
828781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
828881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned),
828981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, unpinned)
829081fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
829181fea08280784b319b936a3506788d595c6ce2adYorke Lee
8292dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        final ArrayList<ContentProviderOperation> operations =
8293dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                new ArrayList<ContentProviderOperation>();
829481fea08280784b319b936a3506788d595c6ce2adYorke Lee
8295dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i1.mContactId, 1, true));
8296dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i3.mContactId, 3, true));
8297dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i4.mContactId, 2, false));
8298dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8299dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
830081fea08280784b319b936a3506788d595c6ce2adYorke Lee
830181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
830281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
830381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
830481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3, Contacts.STARRED, 1),
8305dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
830681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
830781fea08280784b319b936a3506788d595c6ce2adYorke Lee
830881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // Make sure the values are propagated to raw contacts
830981fea08280784b319b936a3506788d595c6ce2adYorke Lee
831081fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
831181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
831281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned),
831381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
831481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, 2)
831581fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
831681fea08280784b319b936a3506788d595c6ce2adYorke Lee
8317dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.clear();
8318dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8319dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        // Now unpin the contact
8320dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i3.mContactId, unpinned, false));
8321dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8322dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
832381fea08280784b319b936a3506788d595c6ce2adYorke Lee
832481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
832581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
832681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
832781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, unpinned, Contacts.STARRED, 0),
8328dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                cv(Contacts._ID, i4.mContactId, Contacts.PINNED, 2, Contacts.STARRED, 0)
832981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
833081fea08280784b319b936a3506788d595c6ce2adYorke Lee
833181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
833281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mRawContactId, RawContacts.PINNED, 1, RawContacts.STARRED, 1),
833381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mRawContactId, RawContacts.PINNED, unpinned,
833481fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
833581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i3.mRawContactId, RawContacts.PINNED, unpinned,
833681fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0),
833781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i4.mRawContactId, RawContacts.PINNED, 2, RawContacts.STARRED, 0)
833881fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
833981fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
834081fea08280784b319b936a3506788d595c6ce2adYorke Lee
834181fea08280784b319b936a3506788d595c6ce2adYorke Lee    public void testPinnedPositionsAfterJoinAndSplit() {
834281fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
834381fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
834481fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
834581fea08280784b319b936a3506788d595c6ce2adYorke Lee        final DatabaseAsserts.ContactIdPair i4 = DatabaseAsserts.assertAndCreateContact(mResolver);
834645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i5 = DatabaseAsserts.assertAndCreateContact(mResolver);
834745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i6 = DatabaseAsserts.assertAndCreateContact(mResolver);
834881fea08280784b319b936a3506788d595c6ce2adYorke Lee
8349dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        final ArrayList<ContentProviderOperation> operations =
8350dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                new ArrayList<ContentProviderOperation>();
8351dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8352dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i1.mContactId, 1, true));
8353dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i2.mContactId, 2, true));
8354dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i3.mContactId, 3, true));
8355dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i5.mContactId, 5, true));
8356dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i6.mContactId, 6, true));
8357dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8358dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
835981fea08280784b319b936a3506788d595c6ce2adYorke Lee
836081fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 1 and 4 together.
836181fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i1.mRawContactId,
836281fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
836381fea08280784b319b936a3506788d595c6ce2adYorke Lee
836481fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If only one contact is pinned, the resulting contact should inherit the pinned position
836581fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
836681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
836781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
836845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, 3),
836945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
837045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
837181fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
837281fea08280784b319b936a3506788d595c6ce2adYorke Lee
837381fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
837481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
837581fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
837681fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
837781fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
837881fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
837981fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
838081fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
838145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
838245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
838345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
838445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
838545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
838681fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
838781fea08280784b319b936a3506788d595c6ce2adYorke Lee
838881fea08280784b319b936a3506788d595c6ce2adYorke Lee        // aggregate raw contact 2 and 3 together.
838981fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i2.mRawContactId,
839081fea08280784b319b936a3506788d595c6ce2adYorke Lee                i3.mRawContactId);
839181fea08280784b319b936a3506788d595c6ce2adYorke Lee
839281fea08280784b319b936a3506788d595c6ce2adYorke Lee        // If both raw contacts are pinned, the resulting contact should inherit the lower
839381fea08280784b319b936a3506788d595c6ce2adYorke Lee        // pinned position
839481fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
839581fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
839645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
839745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 5),
839845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
839981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
840081fea08280784b319b936a3506788d595c6ce2adYorke Lee
840181fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
840281fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1),
840381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2),
840481fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3),
840545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED,
840645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        PinnedPositions.UNPINNED),
840745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5),
840845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6)
840981fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
841081fea08280784b319b936a3506788d595c6ce2adYorke Lee
841181fea08280784b319b936a3506788d595c6ce2adYorke Lee        // split the aggregated raw contacts
841281fea08280784b319b936a3506788d595c6ce2adYorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_SEPARATE, i1.mRawContactId,
841381fea08280784b319b936a3506788d595c6ce2adYorke Lee                i4.mRawContactId);
841481fea08280784b319b936a3506788d595c6ce2adYorke Lee
841581fea08280784b319b936a3506788d595c6ce2adYorke Lee        // raw contacts should be unpinned after being split, but still starred
841681fea08280784b319b936a3506788d595c6ce2adYorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
841781fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
841881fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
841981fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, 2,
842081fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
842181fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i3.mRawContactId, RawContacts.PINNED, 3,
842281fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 1),
842381fea08280784b319b936a3506788d595c6ce2adYorke Lee                cv(RawContacts._ID, i4.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
842445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0),
842545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i5.mRawContactId, RawContacts.PINNED, 5,
842645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
842745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i6.mRawContactId, RawContacts.PINNED, 6,
842845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1)
842945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
843045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
843145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // now demote contact 5
8432dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.clear();
8433dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i5.mContactId, PinnedPositions.DEMOTED, false));
8434dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
843545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
843645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Get new contact Ids for contacts composing of raw contacts 1 and 4 because they have
843745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // changed.
843845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
843945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
844045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
844145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
844245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
844345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
844445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
844545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED),
844645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i6.mContactId, Contacts.PINNED, 6)
844745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
844845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
844945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // aggregate contacts 5 and 6 together
845045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        setAggregationException(AggregationExceptions.TYPE_KEEP_TOGETHER, i5.mRawContactId,
845145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                i6.mRawContactId);
845245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
845345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // The resulting contact should have a pinned value of 6
845445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
845545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId1, Contacts.PINNED, PinnedPositions.UNPINNED),
845645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 2),
845745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, cId4, Contacts.PINNED, PinnedPositions.UNPINNED),
845845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i5.mContactId, Contacts.PINNED, 6)
845945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
846045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    }
846145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
8462dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee    public void testPinnedPositionsDemoteIllegalArguments() {
8463dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        try {
8464dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
8465dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                    null, null);
8466dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            fail();
8467dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        } catch (IllegalArgumentException expected) {
8468dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        }
8469dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8470dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        try {
8471dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
8472dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                    "1.1", null);
8473dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            fail();
8474dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        } catch (IllegalArgumentException expected) {
8475dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        }
8476dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8477dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        try {
8478dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
8479dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                    "NotANumber", null);
8480dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee            fail();
8481dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        } catch (IllegalArgumentException expected) {
8482dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        }
8483dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
8484dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        // Valid contact ID that does not correspond to an actual contact is silently ignored
8485dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD, "999",
8486dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                null);
8487dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee    }
8488dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
848945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee    public void testPinnedPositionsAfterDemoteAndUndemote() {
849045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
849145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
849245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
849345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Pin contact 1 and demote contact 2
8494dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        final ArrayList<ContentProviderOperation> operations =
8495dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                new ArrayList<ContentProviderOperation>();
84964a47775ab4008165328ddab97f5151ddd94d9ab8Yorke Lee        operations.add(newPinningOperation(i1.mContactId, 1, true));
8497dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        operations.add(newPinningOperation(i2.mContactId, PinnedPositions.DEMOTED, false));
8498dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
849945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
850045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
85014a47775ab4008165328ddab97f5151ddd94d9ab8Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
850245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.DEMOTED,
850345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
850445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
850545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
850645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
85074a47775ab4008165328ddab97f5151ddd94d9ab8Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
850845b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
850945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.DEMOTED,
851045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 0)
851145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
851245b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
851345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Now undemote both contacts
8514dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
8515dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                String.valueOf(i1.mContactId), null);
8516dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,
8517dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee                String.valueOf(i2.mContactId), null);
8518dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
851945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
852045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        // Contact 1 remains pinned at 0, while contact 2 becomes unpinned
852145b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
85224a47775ab4008165328ddab97f5151ddd94d9ab8Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1, Contacts.STARRED, 1),
852345b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED,
852445b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        Contacts.STARRED, 0)
852545b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        );
852645b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee
852745b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee        assertStoredValuesWithProjection(RawContacts.CONTENT_URI,
85284a47775ab4008165328ddab97f5151ddd94d9ab8Yorke Lee                cv(RawContacts._ID, i1.mRawContactId, RawContacts.PINNED, 1,
852945b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                        RawContacts.STARRED, 1),
853045b023e89d87b66e44c1b79c6e1444ec9db70a82Yorke Lee                cv(RawContacts._ID, i2.mRawContactId, RawContacts.PINNED, PinnedPositions.UNPINNED,
853181fea08280784b319b936a3506788d595c6ce2adYorke Lee                        RawContacts.STARRED, 0)
853281fea08280784b319b936a3506788d595c6ce2adYorke Lee        );
853381fea08280784b319b936a3506788d595c6ce2adYorke Lee    }
853481fea08280784b319b936a3506788d595c6ce2adYorke Lee
853596062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    /**
853696062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     * Verifies that any existing pinned contacts have their pinned positions incremented by one
853796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     * after the upgrade step
853896062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     */
853996062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    public void testPinnedPositionsUpgradeTo906_PinnedContactsIncrementedByOne() {
854096062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
854196062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
854296062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final DatabaseAsserts.ContactIdPair i3 = DatabaseAsserts.assertAndCreateContact(mResolver);
854396062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final ArrayList<ContentProviderOperation> operations =
854496062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                new ArrayList<ContentProviderOperation>();
854596062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        operations.add(newPinningOperation(i1.mContactId, 0, true));
854696062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        operations.add(newPinningOperation(i2.mContactId, 5, true));
854796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        operations.add(newPinningOperation(i3.mContactId, Integer.MAX_VALUE - 2, true));
854896062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
854996062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
855096062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final ContactsDatabaseHelper helper =
855196062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                ((ContactsDatabaseHelper) ((ContactsProvider2) getProvider()).getDatabaseHelper());
855296062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        SQLiteDatabase db = helper.getWritableDatabase();
855396062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        helper.upgradeToVersion906(db);
855496062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
855596062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 1),
855696062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 6),
855796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                cv(Contacts._ID, i3.mContactId, Contacts.PINNED, Integer.MAX_VALUE - 1)
855896062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        );
855996062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    }
856096062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
856196062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    /**
856296062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     * Verifies that any unpinned contacts (or those with pinned position Integer.MAX_VALUE - 1)
856396062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     * have their pinned positions correctly set to 0 after the upgrade step.
856496062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee     */
856596062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    public void testPinnedPositionsUpgradeTo906_UnpinnedValueCorrectlyUpdated() {
856696062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
856796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final DatabaseAsserts.ContactIdPair i2 = DatabaseAsserts.assertAndCreateContact(mResolver);
856896062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final ArrayList<ContentProviderOperation> operations =
856996062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                new ArrayList<ContentProviderOperation>();
857096062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        operations.add(newPinningOperation(i1.mContactId, Integer.MAX_VALUE -1 , true));
857196062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        operations.add(newPinningOperation(i2.mContactId, Integer.MAX_VALUE, true));
857296062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        CommonDatabaseUtils.applyBatch(mResolver, operations);
857396062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
857496062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        final ContactsDatabaseHelper helper =
857596062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                ((ContactsDatabaseHelper) ((ContactsProvider2) getProvider()).getDatabaseHelper());
857696062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        SQLiteDatabase db = helper.getWritableDatabase();
857796062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        helper.upgradeToVersion906(db);
857896062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
857996062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
858096062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 0),
858196062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee                cv(Contacts._ID, i2.mContactId, Contacts.PINNED, 0)
858296062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee        );
858396062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee    }
858496062013ec40d4b60dd162a6e4a7146690247a3eYorke Lee
85858e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee    /**
85868e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee     * Tests the functionality of the
85878e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee     * {@link ContactsContract.PinnedPositions#pin(ContentResolver, long, int)} API.
85888e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee     */
85898e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee    public void testPinnedPositions_ContactsContractPinnedPositionsPin() {
85908e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        final DatabaseAsserts.ContactIdPair i1 = DatabaseAsserts.assertAndCreateContact(mResolver);
85918e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
85928e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
85938e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
85948e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        );
85958e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
85968e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        ContactsContract.PinnedPositions.pin(mResolver,  i1.mContactId, 5);
85978e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
85988e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
85998e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, 5)
86008e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        );
86018e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
86028e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        ContactsContract.PinnedPositions.pin(mResolver,  i1.mContactId, PinnedPositions.UNPINNED);
86038e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
86048e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        assertStoredValuesWithProjection(Contacts.CONTENT_URI,
86058e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee                cv(Contacts._ID, i1.mContactId, Contacts.PINNED, PinnedPositions.UNPINNED)
86068e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee        );
86078e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee    }
86088e8bd80fe4940972c7a2deb0c3fb2eeaa46a2365Yorke Lee
8609dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee    private ContentProviderOperation newPinningOperation(long id, int pinned, boolean star) {
8610dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        final Uri uri = Uri.withAppendedPath(Contacts.CONTENT_URI, String.valueOf(id));
8611dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        final ContentValues values = new ContentValues();
8612dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        values.put(Contacts.PINNED, pinned);
8613dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        values.put(Contacts.STARRED, star ? 1 : 0);
8614dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee        return ContentProviderOperation.newUpdate(uri).withValues(values).build();
8615dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee    }
8616dcffbdc062336c5403f9f5e1aadbba3f49db335fYorke Lee
861781fea08280784b319b936a3506788d595c6ce2adYorke Lee    /**
861881fea08280784b319b936a3506788d595c6ce2adYorke Lee     * End pinning support tests
861981fea08280784b319b936a3506788d595c6ce2adYorke Lee     ******************************************************/
86208ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng
8621dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    private Cursor queryGroupMemberships(Account account) {
86228ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        Cursor c = mResolver.query(TestUtil.maybeAddAccountQueryParameters(Data.CONTENT_URI,
86238ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng                account),
8624dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                new String[]{GroupMembership.GROUP_ROW_ID, GroupMembership.RAW_CONTACT_ID},
8625dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                Data.MIMETYPE + "=?", new String[]{GroupMembership.CONTENT_ITEM_TYPE},
8626dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana                GroupMembership.GROUP_SOURCE_ID);
8627dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana        return c;
8628dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana    }
8629dd5c25c65f09ada246c826fb6d04f0b6d4cf4388Fred Quintana
863042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    private String readToEnd(FileInputStream inputStream) {
863142aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        try {
8632bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            System.out.println("DECLARED INPUT STREAM LENGTH: " + inputStream.available());
863342aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            int ch;
863442aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            StringBuilder stringBuilder = new StringBuilder();
8635bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            int index = 0;
8636bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            while (true) {
8637bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                ch = inputStream.read();
8638bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                System.out.println("READ CHARACTER: " + index + " " + ch);
8639bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                if (ch == -1) {
8640bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                    break;
8641bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                }
864242aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann                stringBuilder.append((char)ch);
8643bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov                index++;
8644bf732767b4d4d7104e4723bda7d3b0eb0f909997Dmitri Plotnikov            }
864542aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return stringBuilder.toString();
864642aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        } catch (IOException e) {
864742aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann            return null;
864842aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann        }
864942aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann    }
865042aff67de3f0f4b8664a74fe6ff63ae191aa51bfDaniel Lehmann
8651f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    private void assertQueryParameter(String uriString, String parameter, String expectedValue) {
8652f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov        assertEquals(expectedValue, ContactsProvider2.getQueryParameter(
8653f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov                Uri.parse(uriString), parameter));
8654f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov    }
8655f7f747a00f4fa7a9e564507693419a5a8db0eb8fDmitri Plotnikov
86564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private long createContact(ContentValues values, String firstName, String givenName,
86574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8658aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
865924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createContact(values, firstName, givenName, phoneNumber, email, presenceStatus,
866024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, false);
866124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
866224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
866324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createContact(ContentValues values, String firstName, String givenName,
866424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
866524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
866648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return queryContactId(createRawContact(values, firstName, givenName, phoneNumber, email,
866724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                presenceStatus, timesContacted, starred, groupId, chatMode, isUserProfile));
866848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
866948786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
867048786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String firstName, String givenName,
867148786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
8672aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            long groupId, int chatMode) {
867348786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
8674aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori                timesContacted, starred, groupId, chatMode);
86758ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
867648786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
867748786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    }
867848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov
867924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String firstName, String givenName,
868024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            String phoneNumber, String email, int presenceStatus, int timesContacted, int starred,
868124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            long groupId, int chatMode, boolean isUserProfile) {
868224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long rawContactId = createRawContact(values, phoneNumber, email, presenceStatus,
868324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                timesContacted, starred, groupId, chatMode, isUserProfile);
86848ed367fdc0b086d54c489f68d555e2f0a4035f63Chiao Cheng        DataUtil.insertStructuredName(mResolver, rawContactId, firstName, givenName);
868524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return rawContactId;
868624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
868724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
868848786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov    private long createRawContact(ContentValues values, String phoneNumber, String email,
8689aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode) {
869024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return createRawContact(values, phoneNumber, email, presenceStatus, timesContacted, starred,
869124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                groupId, chatMode, false);
869224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
869324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
869424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createRawContact(ContentValues values, String phoneNumber, String email,
869524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            int presenceStatus, int timesContacted, int starred, long groupId, int chatMode,
869624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro            boolean isUserProfile) {
86974a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.STARRED, starred);
86984a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.SEND_TO_VOICEMAIL, 1);
86994a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.CUSTOM_RINGTONE, "beethoven5");
87004a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(RawContacts.TIMES_CONTACTED, timesContacted);
870124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
870224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri insertionUri = isUserProfile
870324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                ? Profile.CONTENT_RAW_CONTACTS_URI
870424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                : RawContacts.CONTENT_URI;
870524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        Uri rawContactUri = mResolver.insert(insertionUri, values);
87064a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long rawContactId = ContentUris.parseId(rawContactUri);
87074a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        Uri photoUri = insertPhoto(rawContactId);
87084a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        long photoId = ContentUris.parseId(photoUri);
87094a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Contacts.PHOTO_ID, photoId);
87109dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(phoneNumber)) {
87119dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertPhoneNumber(rawContactId, phoneNumber);
87129dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
87139dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        if (!TextUtils.isEmpty(email)) {
87149dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa            insertEmail(rawContactId, email);
87159dbfd650ccf93714f3266e80f9fbdbcb526ae7b3Daisuke Miyakawa        }
87164a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
8717aabcd1d34a71ad06ee0a9395331540484f1ceb17Vasu Nori        insertStatusUpdate(Im.PROTOCOL_GOOGLE_TALK, null, email, presenceStatus, "hacking",
87185d0a768b56ed4bd0dfef81b8389247ba74766659Dave Santoro                chatMode, isUserProfile);
87194a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
87204a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        if (groupId != 0) {
87214a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov            insertGroupMembership(rawContactId, groupId);
87224a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        }
872324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
872448786768751cdd9868fb3cf3c82d63f277a54b6fDmitri Plotnikov        return rawContactId;
87254a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
87264a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov
872724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
872824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values under the user's profile.
872924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param profileValues Values to be used to create the entry (common values will be
873024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
873124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
873224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
873324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicProfileContact(ContentValues profileValues) {
873424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long profileRawContactId = createRawContact(profileValues, "Mia", "Prophyl",
873524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18005554411", "mia.prophyl@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
873624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, true);
873724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        profileValues.put(Contacts.DISPLAY_NAME, "Mia Prophyl");
873824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return profileRawContactId;
873924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
874024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
874124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    /**
874224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * Creates a raw contact with pre-set values that is not under the user's profile.
874324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @param nonProfileValues Values to be used to create the entry (common values will be
874424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     *     automatically populated in createRawContact()).
874524c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     * @return the raw contact ID that was created.
874624c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro     */
874724c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    private long createBasicNonProfileContact(ContentValues nonProfileValues) {
874824c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        long nonProfileRawContactId = createRawContact(nonProfileValues, "John", "Doe",
874924c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                "18004664411", "goog411@acme.com", StatusUpdates.INVISIBLE, 4, 1, 0,
875024c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro                StatusUpdates.CAPABILITY_HAS_CAMERA, false);
875124c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        nonProfileValues.put(Contacts.DISPLAY_NAME, "John Doe");
875224c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro        return nonProfileRawContactId;
875324c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro    }
875424c1d384b45a6d3c1cc959062a9d4308335fabbfDave Santoro
87554a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    private void putDataValues(ContentValues values, long rawContactId) {
87564a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RAW_CONTACT_ID, rawContactId);
87574a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.MIMETYPE, "testmimetype");
87584a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.RES_PACKAGE, "oldpackage");
87594a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_PRIMARY, 1);
87604a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.IS_SUPER_PRIMARY, 1);
87614a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA1, "one");
87624a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA2, "two");
87634a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA3, "three");
87644a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA4, "four");
87654a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA5, "five");
87664a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA6, "six");
87674a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA7, "seven");
87684a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA8, "eight");
87694a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA9, "nine");
87704a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA10, "ten");
87714a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA11, "eleven");
87724a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA12, "twelve");
87734a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA13, "thirteen");
87744a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA14, "fourteen");
87754a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.DATA15, "fifteen");
87764a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC1, "sync1");
87774a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC2, "sync2");
87784a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC3, "sync3");
87794a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov        values.put(Data.SYNC4, "sync4");
87804a023070dab9a069be4cac5f5ba5554b66238484Dmitri Plotnikov    }
87814928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa
87824928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    /**
87834928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param data1 email address or phone number
87844928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param usageType One of {@link DataUsageFeedback#USAGE_TYPE}
87854928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * @param values ContentValues for this feedback. Useful for incrementing
87864928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     * {Contacts#TIMES_CONTACTED} in the ContentValue. Can be null.
87874928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa     */
87884928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    private void sendFeedback(String data1, String usageType, ContentValues values) {
87894928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        final long dataId = getStoredLongValue(Data.CONTENT_URI,
87904928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa                Data.DATA1 + "=?", new String[] { data1 }, Data._ID);
8791dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        MoreAsserts.assertNotEqual(0, updateDataUsageFeedback(usageType, dataId));
87924928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        if (values != null && values.containsKey(Contacts.TIMES_CONTACTED)) {
87934928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa            values.put(Contacts.TIMES_CONTACTED, values.getAsInteger(Contacts.TIMES_CONTACTED) + 1);
87944928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa        }
87954928b8c8c7a49ec088884cd9d330eeecc811dca9Daisuke Miyakawa    }
8796dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki
8797dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    private void updateDataUsageFeedback(String usageType, Uri resultUri) {
8798dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final long id = ContentUris.parseId(resultUri);
8799dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        final boolean successful = updateDataUsageFeedback(usageType, id) > 0;
8800dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng        assertTrue(successful);
8801dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng    }
8802dacd5de146b413de86d38b6f56a3fe0b2af4b155Chiao Cheng
8803dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    private int updateDataUsageFeedback(String usageType, long... ids) {
8804dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        final StringBuilder idList = new StringBuilder();
8805dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        for (long id : ids) {
8806dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            if (idList.length() > 0) idList.append(",");
8807dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki            idList.append(id);
8808dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        }
8809dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki        return mResolver.update(DataUsageFeedback.FEEDBACK_URI.buildUpon()
8810dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendPath(idList.toString())
8811dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .appendQueryParameter(DataUsageFeedback.USAGE_TYPE, usageType)
8812dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki                .build(), new ContentValues(), null, null);
8813dfab50ecd585e55769dea451cb3a47ff69b8b86dMakoto Onuki    }
8814a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8815a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasChineseCollator() {
8816a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8817a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8818a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.CHINA)) {
8819a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8820a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8821a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8822a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8823a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
8824a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner
8825a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    private boolean hasJapaneseCollator() {
8826a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
8827a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        for (int i = 0; i < locale.length; i++) {
8828a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            if (locale[i].equals(Locale.JAPAN)) {
8829a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner                return true;
8830a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner            }
8831a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        }
8832a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner        return false;
8833a6a9fa802d1b56c206c670ca1d313bc64effcb5dJay Shrauner    }
88341f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner
88351f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    private boolean hasGermanCollator() {
88361f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        final Locale locale[] = Collator.getAvailableLocales();
88371f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        for (int i = 0; i < locale.length; i++) {
88381f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            if (locale[i].equals(Locale.GERMANY)) {
88391f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner                return true;
88401f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner            }
88411f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        }
88421f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner        return false;
88431f8895bc9efd6c20adb02652bccb2c011ebca114Jay Shrauner    }
8844d35d9c748af4c3182679c4c546137acfc11eb7a8Dmitri Plotnikov}
8845