1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package android.provider.cts.contacts;
18 
19 import android.content.ContentResolver;
20 import android.content.ContentUris;
21 import android.content.ContentValues;
22 import android.database.Cursor;
23 import android.net.Uri;
24 import android.provider.ContactsContract;
25 import android.provider.ContactsContract.AggregationExceptions;
26 
27 import junit.framework.Assert;
28 
29 /**
30  * Convenience methods for operating on the Contacts table.
31  */
32 public class ContactUtil {
33 
34     private static final Uri URI = ContactsContract.Contacts.CONTENT_URI;
35 
update(ContentResolver resolver, long contactId, ContentValues values)36     public static void update(ContentResolver resolver, long contactId,
37             ContentValues values) {
38         Uri uri = ContentUris.withAppendedId(URI, contactId);
39         resolver.update(uri, values, null, null);
40     }
41 
delete(ContentResolver resolver, long contactId)42     public static void delete(ContentResolver resolver, long contactId) {
43         Uri uri = ContentUris.withAppendedId(URI, contactId);
44         resolver.delete(uri, null, null);
45     }
46 
recordExistsForContactId(ContentResolver resolver, long contactId)47     public static boolean recordExistsForContactId(ContentResolver resolver, long contactId) {
48         String[] projection = new String[]{
49                 ContactsContract.Contacts._ID
50         };
51         Uri uri = ContentUris.withAppendedId(URI, contactId);
52         Cursor cursor = resolver.query(uri, projection, null, null, null);
53         if (cursor.moveToNext()) {
54             return true;
55         }
56         return false;
57     }
58 
queryContactLastUpdatedTimestamp(ContentResolver resolver, long contactId)59     public static long queryContactLastUpdatedTimestamp(ContentResolver resolver, long contactId) {
60         String[] projection = new String[]{
61                 ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
62         };
63 
64         Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
65         Cursor cursor = resolver.query(uri, projection, null, null, null);
66         try {
67             if (cursor.moveToNext()) {
68                 return cursor.getLong(0);
69             }
70         } finally {
71             if (cursor != null) {
72                 cursor.close();
73             }
74         }
75         return CommonDatabaseUtils.NOT_FOUND;
76     }
77 
78     /**
79      * Verifies that the number of object parameters is either zero or even, inserts them
80      * into a new ContentValues object as a set of name-value pairs, and returns the newly created
81      * ContentValues object. Throws an exception if the number of string parameters is odd, or a
82      * single null parameter was provided.
83      *
84      * @param namesAndValues Zero or even number of object parameters to convert into name-value
85      * pairs
86      *
87      * @return newly created ContentValues containing the provided name-value pairs
88      */
newContentValues(Object... namesAndValues)89     public static ContentValues newContentValues(Object... namesAndValues) {
90         // Checks that the number of provided parameters is zero or even.
91         Assert.assertEquals(0, namesAndValues.length % 2);
92         final ContentValues contentValues = new ContentValues();
93         for (int i = 0; i < namesAndValues.length - 1; i += 2) {
94             Assert.assertNotNull(namesAndValues[i]);
95             final String name = namesAndValues[i].toString();
96             final Object value = namesAndValues[i + 1];
97             if (value == null) {
98                 contentValues.putNull(name);
99             } else if (value instanceof String) {
100                 contentValues.put(name, (String) value);
101             } else if (value instanceof Integer) {
102                 contentValues.put(name, (Integer) value);
103             } else if (value instanceof Long) {
104                 contentValues.put(name, (Long) value);
105             } else {
106                 Assert.fail("Unsupported value type: " + value.getClass().getSimpleName() + " for "
107                     + " name: " + name);
108             }
109         }
110         return contentValues;
111     }
112 
113     /**
114      * Updates the content resolver with two given raw contact ids and an aggregation type to
115      * manually trigger the forced aggregation, splitting of two raw contacts or specify that
116      * the provider should automatically decide whether or not to aggregate the two raw contacts.
117      *
118      * @param resolver ContentResolver from a valid context
119      * @param type One of the following aggregation exception types:
120      * {@link AggregationExceptions#TYPE_AUTOMATIC},
121      * {@link AggregationExceptions#TYPE_KEEP_SEPARATE},
122      * {@link AggregationExceptions#TYPE_KEEP_TOGETHER}
123      * @param rawContactId1 Id of the first raw contact
124      * @param rawContactId2 Id of the second raw contact
125      */
setAggregationException(ContentResolver resolver, int type, long rawContactId1, long rawContactId2)126     public static void setAggregationException(ContentResolver resolver, int type,
127         long rawContactId1, long rawContactId2) {
128         ContentValues values = new ContentValues();
129         values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
130         values.put(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
131         values.put(AggregationExceptions.TYPE, type);
132         // Actually set the aggregation exception in the contacts database, and check that a
133         // single row was updated.
134         Assert.assertEquals(1, resolver.update(AggregationExceptions.CONTENT_URI, values, null,
135                   null));
136     }
137 }