Support for phones_with_presence URI
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 777315e..4924192 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -159,6 +159,8 @@
private static final int SEARCH_SUGGESTIONS = 12001;
private static final int SEARCH_SHORTCUT = 12002;
+ private static final int PHONES_WITH_PRESENCE = 13000;
+
private interface ContactsQuery {
public static final String TABLE = Tables.RAW_CONTACTS;
@@ -299,6 +301,8 @@
private static final HashMap<String, String> sSettingsProjectionMap;
/** Contains Presence columns */
private static final HashMap<String, String> sPresenceProjectionMap;
+ /** Contains Presence columns */
+ private static final HashMap<String, String> sPhonesWithPresenceProjectionMap;
/** Sql select statement that returns the contact id associated with a data record. */
private static final String sNestedRawContactIdSelect;
@@ -316,6 +320,7 @@
private static final String sSetSuperPrimaryWhere;
/** Sql where statement for filtering on groups. */
private static final String sContactsInGroupSelect;
+
/** Precompiled sql statement for setting a data record to the primary. */
private SQLiteStatement mSetPrimaryStatement;
/** Precompiled sql statement for setting a data record to the super primary. */
@@ -381,6 +386,11 @@
matcher.addURI(ContactsContract.AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/#",
SEARCH_SHORTCUT);
+ // Private API
+ matcher.addURI(ContactsContract.AUTHORITY, "phones_with_presence", PHONES_WITH_PRESENCE);
+ }
+
+ static {
sContactsProjectionMap = new HashMap<String, String>();
sContactsProjectionMap.put(Contacts._ID, Contacts._ID);
sContactsProjectionMap.put(Contacts.DISPLAY_NAME, Contacts.DISPLAY_NAME);
@@ -552,7 +562,6 @@
columns.put(Settings.SHOULD_SYNC, Settings.SHOULD_SYNC);
sSettingsProjectionMap = columns;
-
columns = new HashMap<String, String>();
columns.put(Presence._ID, Presence._ID);
columns.put(Presence.RAW_CONTACT_ID, Presence.RAW_CONTACT_ID);
@@ -564,6 +573,23 @@
columns.put(Presence.PRESENCE_CUSTOM_STATUS, Presence.PRESENCE_CUSTOM_STATUS);
sPresenceProjectionMap = columns;
+ sPhonesWithPresenceProjectionMap = new HashMap<String, String>();
+ sPhonesWithPresenceProjectionMap.put(Phone.NUMBER, Phone.NUMBER);
+ sPhonesWithPresenceProjectionMap.put(Phone.TYPE, Phone.TYPE);
+ sPhonesWithPresenceProjectionMap.put(Phone.LABEL, Phone.LABEL);
+ sPhonesWithPresenceProjectionMap.put(Contacts.DISPLAY_NAME,
+ ContactsColumns.CONCRETE_DISPLAY_NAME + " AS " + Contacts.DISPLAY_NAME);
+ sPhonesWithPresenceProjectionMap.put(Contacts._ID,
+ ContactsColumns.CONCRETE_ID + " AS " + Contacts._ID);
+ sPhonesWithPresenceProjectionMap.put(RawContacts.CONTACT_ID,
+ ContactsColumns.CONCRETE_ID + " AS " + RawContacts.CONTACT_ID);
+ sPhonesWithPresenceProjectionMap.put(Presence.PRESENCE_STATUS,
+ "MAX(" + Presence.PRESENCE_STATUS + ") AS " + Presence.PRESENCE_STATUS);
+
+ // TODO implement support for latest custom status
+ sPhonesWithPresenceProjectionMap.put(Presence.PRESENCE_CUSTOM_STATUS,
+ "NULL AS " + Presence.PRESENCE_CUSTOM_STATUS);
+
sNestedRawContactIdSelect = "SELECT " + Data.RAW_CONTACT_ID + " FROM " + Tables.DATA + " WHERE "
+ Data._ID + "=?";
sNestedMimetypeSelect = "SELECT " + DataColumns.MIMETYPE_ID + " FROM " + Tables.DATA
@@ -2343,6 +2369,25 @@
break;
}
+ case PHONES_WITH_PRESENCE: {
+ long phoneMimeType = mOpenHelper.getMimeTypeId(Phone.CONTENT_ITEM_TYPE);
+ qb.setTables(Tables.PRESENCE
+ + " JOIN " + mOpenHelper.getRawContactView() + " raw_contacts"
+ + " ON (" + Presence.RAW_CONTACT_ID
+ + "=" + RawContactsColumns.CONCRETE_ID + ")"
+ + " JOIN " + Tables.CONTACTS
+ + " ON (" + ContactsColumns.CONCRETE_ID
+ + "=" + RawContacts.CONTACT_ID + ")"
+ + " JOIN " + Tables.DATA
+ + " ON (" + DataColumns.CONCRETE_RAW_CONTACT_ID
+ + "=" + Presence.RAW_CONTACT_ID
+ + " AND " + DataColumns.MIMETYPE_ID + "=" + phoneMimeType
+ + " AND " + Phone.DATA + " NOT NULL" + ")");
+ qb.setProjectionMap(sPhonesWithPresenceProjectionMap);
+ groupBy = RawContacts.CONTACT_ID + "," + DataColumns.CONCRETE_ID;
+ break;
+ }
+
default:
return mLegacyApiSupport.query(uri, projection, selection, selectionArgs,
sortOrder, limit);
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index a39914b..fea02b0 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -346,6 +346,53 @@
c.close();
}
+ public void testPhonesWithPresence() {
+
+ ContentValues values = new ContentValues();
+ Uri rawContactUri = mResolver.insert(RawContacts.CONTENT_URI, values);
+ long rawContactId = ContentUris.parseId(rawContactUri);
+ insertStructuredName(rawContactId, "John", "Doe");
+ Uri photoUri = insertPhoto(rawContactId);
+ long photoId = ContentUris.parseId(photoUri);
+ values.put(Contacts.PHOTO_ID, photoId);
+ insertPhoneNumber(rawContactId, "18004664411");
+ insertPhoneNumber(rawContactId, "18004664412");
+ insertEmail(rawContactId, "goog411@acme.com");
+ insertEmail(rawContactId, "goog412@acme.com");
+
+ insertPresence(Im.PROTOCOL_GOOGLE_TALK, "goog411@acme.com", Presence.INVISIBLE);
+ insertPresence(Im.PROTOCOL_GOOGLE_TALK, "goog412@acme.com", Presence.AVAILABLE);
+ long contactId = queryContactId(rawContactId);
+
+ Uri uri = Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "phones_with_presence");
+
+ Cursor c = mResolver.query(uri, null,
+ RawContacts.CONTACT_ID + "=" + contactId, null, Phone.NUMBER);
+ assertEquals(2, c.getCount());
+
+ c.moveToFirst();
+
+ values.clear();
+ values.put(Presence.PRESENCE_STATUS, Presence.AVAILABLE);
+ values.put(Contacts.DISPLAY_NAME, "John Doe");
+ values.put(Phone.NUMBER, "18004664411");
+ values.putNull(Phone.LABEL);
+ values.put(Contacts._ID, contactId);
+ assertCursorValues(c, values);
+
+ c.moveToNext();
+
+ values.clear();
+ values.put(Presence.PRESENCE_STATUS, Presence.AVAILABLE);
+ values.put(Contacts.DISPLAY_NAME, "John Doe");
+ values.put(Phone.NUMBER, "18004664412");
+ values.putNull(Phone.LABEL);
+ values.put(Contacts._ID, contactId);
+ assertCursorValues(c, values);
+
+ c.close();
+ }
+
public void testGroupInsert() {
ContentValues values = new ContentValues();