Merge "Remove Phone capabilities from devices that do not have Phone/SMS apps"
diff --git a/src/com/android/contacts/util/Constants.java b/src/com/android/contacts/util/Constants.java
index 433d54d..4e80345 100644
--- a/src/com/android/contacts/util/Constants.java
+++ b/src/com/android/contacts/util/Constants.java
@@ -16,7 +16,6 @@
 
 package com.android.contacts.util;
 
-import android.app.Service;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 
 public class Constants {
diff --git a/src/com/android/contacts/util/PhoneCapabilityTester.java b/src/com/android/contacts/util/PhoneCapabilityTester.java
new file mode 100644
index 0000000..4b6c17e
--- /dev/null
+++ b/src/com/android/contacts/util/PhoneCapabilityTester.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 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.util;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+
+import java.util.List;
+
+public final class PhoneCapabilityTester {
+    /**
+     * Tests whether the Intent has a receiver registered. This can be used to show/hide
+     * functionality (like Phone, SMS)
+     */
+    public static boolean isIntentRegistered(Context context, Intent intent) {
+        final PackageManager packageManager = context.getPackageManager();
+        final List<ResolveInfo> receiverList = packageManager.queryIntentActivities(intent,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        return receiverList.size() > 0;
+    }
+
+    /**
+     * Returns true if this device has a Phone application installed.
+     */
+    public static boolean isPhoneCallIntentRegistered(Context context) {
+        final Intent intent = new Intent(
+                Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts(Constants.SCHEME_TEL, "", null));
+        return isIntentRegistered(context, intent);
+    }
+
+    /**
+     * Returns true if the device has an SMS application installed.
+     */
+    public static boolean isSmsIntentRegistered(Context context) {
+        final Intent intent = new Intent(Intent.ACTION_SENDTO,
+                Uri.fromParts(Constants.SCHEME_SMSTO, "", null));
+        return isIntentRegistered(context, intent);
+    }
+}
diff --git a/src/com/android/contacts/views/detail/ContactDetailFragment.java b/src/com/android/contacts/views/detail/ContactDetailFragment.java
index 73d0039..fe203a2 100644
--- a/src/com/android/contacts/views/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/views/detail/ContactDetailFragment.java
@@ -28,6 +28,7 @@
 import com.android.contacts.model.ContactsSource.DataKind;
 import com.android.contacts.util.Constants;
 import com.android.contacts.util.DataStatus;
+import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.views.ContactLoader;
 import com.android.internal.telephony.ITelephony;
 
@@ -108,7 +109,6 @@
     private ContactLoader.Result mContactData;
     private ContactDetailHeaderView mHeaderView;
     private ListView mListView;
-    private boolean mShowSmsLinksForAllPhones;
     private ViewAdapter mAdapter;
     private Uri mPrimaryPhoneUri = null;
 
@@ -119,6 +119,16 @@
     private int mNumPhoneNumbers = 0;
 
     /**
+     * Device capability: Set during buildEntries and used in the long-press context menu
+     */
+    private boolean mHasPhone;
+
+    /**
+     * Device capability: Set during buildEntries and used in the long-press context menu
+     */
+    private boolean mHasSms;
+
+    /**
      * The view shown if the detail list is empty.
      * We set this to the list view when first bind the adapter, so that it won't be shown while
      * we're loading data.
@@ -184,9 +194,6 @@
         // Don't set it to mListView yet.  We do so later when we bind the adapter.
         mEmptyView = view.findViewById(android.R.id.empty);
 
-        //TODO Read this value from a preference
-        mShowSmsLinksForAllPhones = true;
-
         return view;
     }
 
@@ -239,6 +246,9 @@
      * Build up the entries to display on the screen.
      */
     private final void buildEntries() {
+        mHasPhone = PhoneCapabilityTester.isPhoneCallIntentRegistered(mContext);
+        mHasSms = PhoneCapabilityTester.isSmsIntentRegistered(mContext);
+
         // Clear out the old entries
         final int numSections = mSections.size();
         for (int i = 0; i < numSections; i++) {
@@ -310,24 +320,32 @@
                     // Build phone entries
                     mNumPhoneNumbers++;
 
-                    entry.intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                            Uri.fromParts(Constants.SCHEME_TEL, entry.data, null));
-                    entry.secondaryIntent = new Intent(Intent.ACTION_SENDTO,
-                            Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null));
+                    final Intent phoneIntent = mHasPhone ? new Intent(Intent.ACTION_CALL_PRIVILEGED,
+                            Uri.fromParts(Constants.SCHEME_TEL, entry.data, null)) : null;
+                    final Intent smsIntent = mHasSms ? new Intent(Intent.ACTION_SENDTO,
+                            Uri.fromParts(Constants.SCHEME_SMSTO, entry.data, null)) : null;
+
+                    // Configure Icons and Intents. Notice actionIcon is already set to the phone
+                    if (mHasPhone && mHasSms) {
+                        entry.intent = phoneIntent;
+                        entry.secondaryIntent = smsIntent;
+                        entry.secondaryActionIcon = kind.iconAltRes;
+                    } else if (mHasPhone) {
+                        entry.intent = phoneIntent;
+                    } else if (mHasSms) {
+                        entry.intent = smsIntent;
+                        entry.actionIcon = kind.iconAltRes;
+                    } else {
+                        entry.intent = null;
+                        entry.actionIcon = -1;
+                    }
+
 
                     // Remember super-primary phone
                     if (isSuperPrimary) mPrimaryPhoneUri = entry.uri;
 
                     entry.isPrimary = isSuperPrimary;
                     mPhoneEntries.add(entry);
-
-                    if (entry.type == CommonDataKinds.Phone.TYPE_MOBILE
-                            || mShowSmsLinksForAllPhones) {
-                        // Add an SMS entry
-                        if (kind.iconAltRes > 0) {
-                            entry.secondaryActionIcon = kind.iconAltRes;
-                        }
-                    }
                 } else if (Email.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
                     // Build email entries
                     entry.intent = new Intent(Intent.ACTION_SENDTO,
@@ -774,6 +792,15 @@
     }
 
     @Override
+    public void onPrepareOptionsMenu(Menu menu) {
+        // Options only shows telephony-related settings (ringtone, send to voicemail).
+        // ==> Hide if we don't have a telephone
+        final MenuItem optionsMenu = menu.findItem(R.id.menu_options);
+        final boolean deviceHasPhone = PhoneCapabilityTester.isPhoneCallIntentRegistered(mContext);
+        optionsMenu.setVisible(deviceHasPhone);
+    }
+
+    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case R.id.menu_edit: {
@@ -848,9 +875,15 @@
         final ViewEntry entry = mAdapter.getEntry(info.position);
         menu.setHeaderTitle(R.string.contactOptionsTitle);
         if (entry.mimetype.equals(CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
-            menu.add(0, 0, 0, R.string.menu_call).setIntent(entry.intent);
-            menu.add(0, 0, 0, R.string.menu_sendSMS).setIntent(entry.secondaryIntent);
-            if (!entry.isPrimary) {
+            if (mHasPhone) {
+                menu.add(0, 0, 0, R.string.menu_call).setIntent(entry.intent);
+            }
+            if (mHasSms) {
+                // If there is no Phone, SMS is the primary intent
+                final Intent intent = mHasPhone ? entry.secondaryIntent : entry.intent;
+                menu.add(0, 0, 0, R.string.menu_sendSMS).setIntent(intent);
+            }
+            if (!entry.isPrimary && mHasPhone) {
                 menu.add(0, MENU_ITEM_MAKE_DEFAULT, 0, R.string.menu_makeDefaultNumber);
             }
         } else if (entry.mimetype.equals(CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {