Adding proper chat capability icons to contact detail

Change-Id: I4d9e01e08a8d70bb6e1591f92436a5ab7c194be6
diff --git a/res/drawable-hdpi/sym_action_audiochat.png b/res/drawable-hdpi/sym_action_audiochat.png
deleted file mode 100644
index 88dc0c5..0000000
--- a/res/drawable-hdpi/sym_action_audiochat.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/sym_action_videochat.png b/res/drawable-hdpi/sym_action_videochat.png
deleted file mode 100644
index c53b4cd..0000000
--- a/res/drawable-hdpi/sym_action_videochat.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/sym_action_audiochat.png b/res/drawable-mdpi/sym_action_audiochat.png
deleted file mode 100644
index 9bbaa37..0000000
--- a/res/drawable-mdpi/sym_action_audiochat.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/sym_action_videochat.png b/res/drawable-mdpi/sym_action_videochat.png
deleted file mode 100644
index 84e1b98..0000000
--- a/res/drawable-mdpi/sym_action_videochat.png
+++ /dev/null
Binary files differ
diff --git a/src/com/android/contacts/ContactPresenceIconUtil.java b/src/com/android/contacts/ContactPresenceIconUtil.java
index 1a2d58e..81a1bed 100644
--- a/src/com/android/contacts/ContactPresenceIconUtil.java
+++ b/src/com/android/contacts/ContactPresenceIconUtil.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.StatusUpdates;
 
 /**
@@ -26,7 +27,7 @@
 public class ContactPresenceIconUtil {
     /**
      * Get the presence icon resource according the status.
-     * 
+     *
      * @return null means don't show the status icon.
      */
     public static Drawable getPresenceIcon (Context context, int status) {
@@ -45,4 +46,41 @@
                 return null;
         }
     }
+
+    public static Drawable getCapabilityIcon(Context context, int status, int chatCapability) {
+        int resourceId = 0;
+        if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
+            switch(status) {
+                case StatusUpdates.AVAILABLE:
+                    resourceId = android.R.drawable.presence_video_online;
+                    break;
+                case StatusUpdates.IDLE:
+                case StatusUpdates.AWAY:
+                    resourceId = android.R.drawable.presence_video_away;
+                    break;
+                case StatusUpdates.DO_NOT_DISTURB:
+                    resourceId = android.R.drawable.presence_video_busy;
+                    break;
+            }
+        } else if ((chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
+            switch(status) {
+                case StatusUpdates.AVAILABLE:
+                    resourceId = android.R.drawable.presence_audio_online;
+                    break;
+                case StatusUpdates.IDLE:
+                case StatusUpdates.AWAY:
+                    resourceId = android.R.drawable.presence_audio_away;
+                    break;
+                case StatusUpdates.DO_NOT_DISTURB:
+                    resourceId = android.R.drawable.presence_audio_busy;
+                    break;
+            }
+        }
+
+        if (resourceId != 0) {
+            return context.getResources().getDrawable(resourceId);
+        }
+
+        return null;
+    }
 }
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 181fb37..0e75a7f 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -16,17 +16,11 @@
 
 package com.android.contacts;
 
-import com.android.contacts.util.Constants;
-
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.location.CountryDetector;
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Data;
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 
@@ -80,120 +74,6 @@
         return null;
     }
 
-    public static final class ImActions {
-        private final Intent mPrimaryIntent;
-        private final Intent mSecondaryIntent;
-        private final int mPrimaryActionIcon;
-        private final int mSecondaryActionIcon;
-
-        private ImActions(Intent primaryIntent, Intent secondaryIntent, int primaryActionIcon,
-                int secondaryActionIcon) {
-            mPrimaryIntent = primaryIntent;
-            mSecondaryIntent = secondaryIntent;
-            mPrimaryActionIcon = primaryActionIcon;
-            mSecondaryActionIcon = secondaryActionIcon;
-        }
-
-        public Intent getPrimaryIntent() {
-            return mPrimaryIntent;
-        }
-
-        public Intent getSecondaryIntent() {
-            return mSecondaryIntent;
-        }
-
-        public int getPrimaryActionIcon() {
-            return mPrimaryActionIcon;
-        }
-
-        public int getSecondaryActionIcon() {
-            return mSecondaryActionIcon;
-        }
-    }
-
-    /**
-     * Build {@link Intent} to launch an action for the given {@link Im} or
-     * {@link Email} row. If the result is non-null, it either contains one or two Intents
-     * (e.g. [Text, Videochat] or just [Text])
-     * Returns null when missing protocol or data.
-     */
-    public static ImActions buildImActions(ContentValues values) {
-        final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(values.getAsString(Data.MIMETYPE));
-
-        if (!isEmail && !isProtocolValid(values)) {
-            return null;
-        }
-
-        final String data = values.getAsString(isEmail ? Email.DATA : Im.DATA);
-        if (TextUtils.isEmpty(data)) return null;
-
-        final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : values.getAsInteger(Im.PROTOCOL);
-
-        if (protocol == Im.PROTOCOL_GOOGLE_TALK) {
-            final Integer chatCapabilityObj = values.getAsInteger(Im.CHAT_CAPABILITY);
-            final int chatCapability = chatCapabilityObj == null ? 0 : chatCapabilityObj;
-            if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
-                // Allow Video chat and Texting
-                return new ImActions(
-                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message")),
-                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call")),
-                        R.drawable.sym_action_talk_holo_light,
-                        R.drawable.sym_action_videochat
-                        );
-            } else if ((chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
-                // Allow Talking and Texting
-                return new ImActions(
-                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message")),
-                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call")),
-                        R.drawable.sym_action_talk_holo_light,
-                        R.drawable.sym_action_audiochat
-                        );
-            } else {
-                return new ImActions(
-                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message")),
-                        null,
-                        R.drawable.sym_action_talk_holo_light,
-                        -1
-                        );
-            }
-        } else {
-            // Build an IM Intent
-            String host = values.getAsString(Im.CUSTOM_PROTOCOL);
-
-            if (protocol != Im.PROTOCOL_CUSTOM) {
-                // Try bringing in a well-known host for specific protocols
-                host = ContactsUtils.lookupProviderNameFromId(protocol);
-            }
-
-            if (!TextUtils.isEmpty(host)) {
-                final String authority = host.toLowerCase();
-                final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
-                        authority).appendPath(data).build();
-                return new ImActions(
-                        new Intent(Intent.ACTION_SENDTO, imUri),
-                        null,
-                        R.drawable.sym_action_talk_holo_light,
-                        -1
-                        );
-            } else {
-                return null;
-            }
-        }
-    }
-
-    private static boolean isProtocolValid(ContentValues values) {
-        String protocolString = values.getAsString(Im.PROTOCOL);
-        if (protocolString == null) {
-            return false;
-        }
-        try {
-            Integer.valueOf(protocolString);
-        } catch (NumberFormatException e) {
-            return false;
-        }
-        return true;
-    }
-
     /**
      * Test if the given {@link CharSequence} contains any graphic characters,
      * first checking {@link TextUtils#isEmpty(CharSequence)} to handle null.
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index d0c1abc..7ff8acd 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -22,7 +22,6 @@
 import com.android.contacts.ContactOptionsActivity;
 import com.android.contacts.ContactPresenceIconUtil;
 import com.android.contacts.ContactsUtils;
-import com.android.contacts.ContactsUtils.ImActions;
 import com.android.contacts.GroupMetaData;
 import com.android.contacts.R;
 import com.android.contacts.TypePrecedence;
@@ -465,13 +464,7 @@
                                 imMime, mContext);
                         final ViewEntry imEntry = ViewEntry.fromValues(mContext,
                                 imMime, imKind, dataId, entryValues);
-                        final ImActions imActions = ContactsUtils.buildImActions(entryValues);
-                        if (imActions != null) {
-                            imEntry.actionIcon = imActions.getPrimaryActionIcon();
-                            imEntry.secondaryActionIcon = imActions.getSecondaryActionIcon();
-                            imEntry.intent = imActions.getPrimaryIntent();
-                            imEntry.secondaryIntent = imActions.getSecondaryIntent();
-                        }
+                        buildImActions(imEntry, entryValues);
                         imEntry.applyStatus(status, false);
                         mImEntries.add(imEntry);
                     }
@@ -482,13 +475,7 @@
                     mPostalEntries.add(entry);
                 } else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build IM entries
-                    final ImActions imActions = ContactsUtils.buildImActions(entryValues);
-                    if (imActions != null) {
-                        entry.actionIcon = imActions.getPrimaryActionIcon();
-                        entry.secondaryActionIcon = imActions.getSecondaryActionIcon();
-                        entry.intent = imActions.getPrimaryIntent();
-                        entry.secondaryIntent = imActions.getSecondaryIntent();
-                    }
+                    buildImActions(entry, entryValues);
 
                     // Apply presence and status details when available
                     final DataStatus status = mContactData.getStatuses().get(entry.id);
@@ -622,9 +609,82 @@
     }
 
     /**
+     * Build {@link Intent} to launch an action for the given {@link Im} or
+     * {@link Email} row. If the result is non-null, it either contains one or two Intents
+     * (e.g. [Text, Videochat] or just [Text])
+     */
+    public static void buildImActions(ViewEntry entry, ContentValues values) {
+        final boolean isEmail = Email.CONTENT_ITEM_TYPE.equals(values.getAsString(Data.MIMETYPE));
+
+        if (!isEmail && !isProtocolValid(values)) {
+            return;
+        }
+
+        final String data = values.getAsString(isEmail ? Email.DATA : Im.DATA);
+        if (TextUtils.isEmpty(data)) {
+            return;
+        }
+
+        final int protocol = isEmail ? Im.PROTOCOL_GOOGLE_TALK : values.getAsInteger(Im.PROTOCOL);
+
+        if (protocol == Im.PROTOCOL_GOOGLE_TALK) {
+            final Integer chatCapabilityObj = values.getAsInteger(Im.CHAT_CAPABILITY);
+            final int chatCapability = chatCapabilityObj == null ? 0 : chatCapabilityObj;
+            entry.chatCapability = chatCapability;
+            if ((chatCapability & Im.CAPABILITY_HAS_CAMERA) != 0) {
+                entry.actionIcon = R.drawable.sym_action_talk_holo_light;
+                entry.intent =
+                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+                entry.secondaryIntent =
+                        new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
+            } else if ((chatCapability & Im.CAPABILITY_HAS_VOICE) != 0) {
+                // Allow Talking and Texting
+                entry.actionIcon = R.drawable.sym_action_talk_holo_light;
+                entry.intent =
+                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+                entry.secondaryIntent =
+                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?call"));
+            } else {
+                entry.actionIcon = R.drawable.sym_action_talk_holo_light;
+                entry.intent =
+                    new Intent(Intent.ACTION_SENDTO, Uri.parse("xmpp:" + data + "?message"));
+            }
+        } else {
+            // Build an IM Intent
+            String host = values.getAsString(Im.CUSTOM_PROTOCOL);
+
+            if (protocol != Im.PROTOCOL_CUSTOM) {
+                // Try bringing in a well-known host for specific protocols
+                host = ContactsUtils.lookupProviderNameFromId(protocol);
+            }
+
+            if (!TextUtils.isEmpty(host)) {
+                final String authority = host.toLowerCase();
+                final Uri imUri = new Uri.Builder().scheme(Constants.SCHEME_IMTO).authority(
+                        authority).appendPath(data).build();
+                entry.actionIcon = R.drawable.sym_action_talk_holo_light;
+                entry.intent = new Intent(Intent.ACTION_SENDTO, imUri);
+            }
+        }
+    }
+
+    private static boolean isProtocolValid(ContentValues values) {
+        String protocolString = values.getAsString(Im.PROTOCOL);
+        if (protocolString == null) {
+            return false;
+        }
+        try {
+            Integer.valueOf(protocolString);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * A basic structure with the data for a contact entry in the list.
      */
-    private static class ViewEntry implements Collapsible<ViewEntry> {
+    static class ViewEntry implements Collapsible<ViewEntry> {
         public int type = -1;
         public String kind;
         public String typeString;
@@ -645,10 +705,11 @@
         public int collapseCount = 0;
 
         public int presence = -1;
+        public int chatCapability = 0;
 
         public CharSequence footerLine = null;
 
-        private ViewEntry() {
+        ViewEntry() {
         }
 
         /**
@@ -889,7 +950,11 @@
             Drawable secondaryActionIcon = null;
             if (entry.secondaryActionIcon != -1) {
                 secondaryActionIcon = resources.getDrawable(entry.secondaryActionIcon);
+            } else if (entry.chatCapability != 0) {
+                secondaryActionIcon = ContactPresenceIconUtil.getCapabilityIcon(
+                        mContext, entry.presence, entry.chatCapability);
             }
+
             if (entry.secondaryIntent != null && secondaryActionIcon != null) {
                 secondaryActionView.setImageDrawable(secondaryActionIcon);
                 secondaryActionView.setTag(entry);
diff --git a/tests/src/com/android/contacts/ContactsUtilsTests.java b/tests/src/com/android/contacts/ContactsUtilsTests.java
index 7e85c32..e8deb11 100644
--- a/tests/src/com/android/contacts/ContactsUtilsTests.java
+++ b/tests/src/com/android/contacts/ContactsUtilsTests.java
@@ -16,122 +16,16 @@
 
 package com.android.contacts;
 
-import com.android.contacts.ContactsUtils.ImActions;
-
-import android.content.ContentValues;
 import android.content.Intent;
-import android.net.Uri;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Im;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
 
 /**
  * Tests for {@link ContactsUtils}.
  */
-@LargeTest
+@SmallTest
 public class ContactsUtilsTests extends AndroidTestCase {
-    private static final String TEST_ADDRESS = "user@example.org";
-    private static final String TEST_PROTOCOL = "prot%col";
-
-    public void testImIntent() throws Exception {
-        // Test GTalk XMPP URI. No chat capabilities provided
-        final ContentValues values = new ContentValues();
-        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        values.put(Im.TYPE, Im.TYPE_HOME);
-        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
-        values.put(Im.DATA, TEST_ADDRESS);
-
-        final ImActions imActions = ContactsUtils.buildImActions(values);
-        final Intent intent = imActions.getPrimaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, intent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?message", intent.getData().toString());
-
-        assertNull(imActions.getSecondaryIntent());
-    }
-
-    public void testImIntentWithAudio() throws Exception {
-        // Test GTalk XMPP URI. Audio chat capabilities provided
-        final ContentValues values = new ContentValues();
-        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        values.put(Im.TYPE, Im.TYPE_HOME);
-        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
-        values.put(Im.DATA, TEST_ADDRESS);
-        values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO);
-
-        final ImActions imActions = ContactsUtils.buildImActions(values);
-        final Intent primaryIntent = imActions.getPrimaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, primaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?message", primaryIntent.getData().toString());
-
-        final Intent secondaryIntent = imActions.getSecondaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, secondaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?call", secondaryIntent.getData().toString());
-    }
-
-    public void testImIntentWithVideo() throws Exception {
-        // Test GTalk XMPP URI. Video chat capabilities provided
-        final ContentValues values = new ContentValues();
-        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        values.put(Im.TYPE, Im.TYPE_HOME);
-        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
-        values.put(Im.DATA, TEST_ADDRESS);
-        values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
-                Im.CAPABILITY_HAS_VOICE);
-
-        final ImActions imActions = ContactsUtils.buildImActions(values);
-        final Intent primaryIntent = imActions.getPrimaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, primaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?message", primaryIntent.getData().toString());
-
-        final Intent secondaryIntent = imActions.getSecondaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, secondaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?call", secondaryIntent.getData().toString());
-    }
-
-    public void testImIntentCustom() throws Exception {
-        // Custom IM types have encoded authority. We send the imto Intent here, because
-        // legacy third party apps might not accept xmpp yet
-        final ContentValues values = new ContentValues();
-        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
-        values.put(Im.TYPE, Im.TYPE_HOME);
-        values.put(Im.PROTOCOL, Im.PROTOCOL_CUSTOM);
-        values.put(Im.CUSTOM_PROTOCOL, TEST_PROTOCOL);
-        values.put(Im.DATA, TEST_ADDRESS);
-
-        final ImActions actions = ContactsUtils.buildImActions(values);
-        final Intent intent = actions.getPrimaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, intent.getAction());
-
-        final Uri data = intent.getData();
-        assertEquals("imto", data.getScheme());
-        assertEquals(TEST_PROTOCOL, data.getAuthority());
-        assertEquals(TEST_ADDRESS, data.getPathSegments().get(0));
-
-        assertNull(actions.getSecondaryIntent());
-    }
-
-    public void testImEmailIntent() throws Exception {
-        // Email addresses are treated as Google Talk entries
-        // This test only tests the VIDEO+CAMERA case. The other cases have been addressed by the
-        // Im tests
-        final ContentValues values = new ContentValues();
-        values.put(Email.MIMETYPE, Email.CONTENT_ITEM_TYPE);
-        values.put(Email.TYPE, Email.TYPE_HOME);
-        values.put(Email.DATA, TEST_ADDRESS);
-        values.put(Email.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
-                Im.CAPABILITY_HAS_VOICE);
-
-        final ImActions imActions = ContactsUtils.buildImActions(values);
-        final Intent primaryIntent = imActions.getPrimaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, primaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?message", primaryIntent.getData().toString());
-
-        final Intent secondaryIntent = imActions.getSecondaryIntent();
-        assertEquals(Intent.ACTION_SENDTO, secondaryIntent.getAction());
-        assertEquals("xmpp:" + TEST_ADDRESS + "?call", secondaryIntent.getData().toString());
-    }
 
     public void testIsGraphicNull() throws Exception {
         assertFalse(ContactsUtils.isGraphic(null));
diff --git a/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
new file mode 100644
index 0000000..4cee32c
--- /dev/null
+++ b/tests/src/com/android/contacts/detail/ContactDetailFragmentTests.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.detail;
+
+import com.android.contacts.detail.ContactDetailFragment.ViewEntry;
+
+import android.content.ContentValues;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Tests for {@link ContactDetailFragment}.
+ */
+@SmallTest
+public class ContactDetailFragmentTests extends AndroidTestCase {
+    private static final String TEST_ADDRESS = "user@example.org";
+    private static final String TEST_PROTOCOL = "prot%col";
+
+    public void testImIntent() throws Exception {
+        // Test GTalk XMPP URI. No chat capabilities provided
+        final ContentValues values = new ContentValues();
+        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.TYPE, Im.TYPE_HOME);
+        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
+        values.put(Im.DATA, TEST_ADDRESS);
+
+        ViewEntry entry = new ContactDetailFragment.ViewEntry();
+        ContactDetailFragment.buildImActions(entry, values);
+        assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
+
+        assertNull(entry.secondaryIntent);
+    }
+
+    public void testImIntentWithAudio() throws Exception {
+        // Test GTalk XMPP URI. Audio chat capabilities provided
+        final ContentValues values = new ContentValues();
+        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.TYPE, Im.TYPE_HOME);
+        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
+        values.put(Im.DATA, TEST_ADDRESS);
+        values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO);
+
+        ViewEntry entry = new ContactDetailFragment.ViewEntry();
+        ContactDetailFragment.buildImActions(entry, values);
+        assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
+
+        assertEquals(Intent.ACTION_SENDTO, entry.secondaryIntent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?call", entry.secondaryIntent.getData().toString());
+    }
+
+    public void testImIntentWithVideo() throws Exception {
+        // Test GTalk XMPP URI. Video chat capabilities provided
+        final ContentValues values = new ContentValues();
+        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.TYPE, Im.TYPE_HOME);
+        values.put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK);
+        values.put(Im.DATA, TEST_ADDRESS);
+        values.put(Im.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
+                Im.CAPABILITY_HAS_VOICE);
+
+        ViewEntry entry = new ContactDetailFragment.ViewEntry();
+        ContactDetailFragment.buildImActions(entry, values);
+        assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
+
+        assertEquals(Intent.ACTION_SENDTO, entry.secondaryIntent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?call", entry.secondaryIntent.getData().toString());
+    }
+
+    public void testImIntentCustom() throws Exception {
+        // Custom IM types have encoded authority. We send the imto Intent here, because
+        // legacy third party apps might not accept xmpp yet
+        final ContentValues values = new ContentValues();
+        values.put(Im.MIMETYPE, Im.CONTENT_ITEM_TYPE);
+        values.put(Im.TYPE, Im.TYPE_HOME);
+        values.put(Im.PROTOCOL, Im.PROTOCOL_CUSTOM);
+        values.put(Im.CUSTOM_PROTOCOL, TEST_PROTOCOL);
+        values.put(Im.DATA, TEST_ADDRESS);
+
+        ViewEntry entry = new ContactDetailFragment.ViewEntry();
+        ContactDetailFragment.buildImActions(entry, values);
+        assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
+
+        final Uri data = entry.intent.getData();
+        assertEquals("imto", data.getScheme());
+        assertEquals(TEST_PROTOCOL, data.getAuthority());
+        assertEquals(TEST_ADDRESS, data.getPathSegments().get(0));
+
+        assertNull(entry.secondaryIntent);
+    }
+
+    public void testImEmailIntent() throws Exception {
+        // Email addresses are treated as Google Talk entries
+        // This test only tests the VIDEO+CAMERA case. The other cases have been addressed by the
+        // Im tests
+        final ContentValues values = new ContentValues();
+        values.put(Email.MIMETYPE, Email.CONTENT_ITEM_TYPE);
+        values.put(Email.TYPE, Email.TYPE_HOME);
+        values.put(Email.DATA, TEST_ADDRESS);
+        values.put(Email.CHAT_CAPABILITY, Im.CAPABILITY_HAS_VOICE | Im.CAPABILITY_HAS_VIDEO |
+                Im.CAPABILITY_HAS_VOICE);
+
+        ViewEntry entry = new ContactDetailFragment.ViewEntry();
+        ContactDetailFragment.buildImActions(entry, values);
+        assertEquals(Intent.ACTION_SENDTO, entry.intent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?message", entry.intent.getData().toString());
+
+        assertEquals(Intent.ACTION_SENDTO, entry.secondaryIntent.getAction());
+        assertEquals("xmpp:" + TEST_ADDRESS + "?call", entry.secondaryIntent.getData().toString());
+    }
+}