Merge "Checks voicemail setting before notifying InCallUi" into klp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fe71d4c..9dc1072 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -40,6 +40,7 @@
     <protected-broadcast android:name="com.android.internal.telephony.data-restart-trysetup" />
     <protected-broadcast android:name="com.android.internal.telephony.data-stall" />
 
+    <uses-permission android:name="android.permission.BIND_CALL_SERVICE" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
diff --git a/src/com/android/phone/BluetoothManager.java b/src/com/android/phone/BluetoothManager.java
index c2b4f7d..ffce465 100644
--- a/src/com/android/phone/BluetoothManager.java
+++ b/src/com/android/phone/BluetoothManager.java
@@ -71,7 +71,6 @@
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
 
         init(mContext);
-        // TODO(klp): Listen for changes to the call list/state.
     }
 
     /* package */ boolean isBluetoothHeadsetAudioOn() {
diff --git a/src/com/android/phone/CallCard.java b/src/com/android/phone/CallCard.java
index 22215c0..bfb14ac 100644
--- a/src/com/android/phone/CallCard.java
+++ b/src/com/android/phone/CallCard.java
@@ -764,14 +764,6 @@
             case INCOMING:
             case WAITING:
                 callStateLabel = context.getString(R.string.card_title_incoming_call);
-
-                // Also, display a special icon (alongside the "Incoming call"
-                // label) if there's an incoming call and audio will be routed
-                // to bluetooth when you answer it.
-                // TODO(klp): Add bluetooth label to new UI screen for incoming calls.
-                //if (mApplication.showBluetoothIndication()) {
-                //    bluetoothIconId = R.drawable.ic_incoming_call_bluetooth;
-                //}
                 break;
 
             case DISCONNECTING:
diff --git a/src/com/android/phone/CallCommandService.java b/src/com/android/phone/CallCommandService.java
index 90297d8..b38517e 100644
--- a/src/com/android/phone/CallCommandService.java
+++ b/src/com/android/phone/CallCommandService.java
@@ -57,7 +57,7 @@
     }
 
     /**
-     * TODO(klp): Add a confirmation callback parameter.
+     * TODO: Add a confirmation callback parameter.
      */
     @Override
     public void answerCall(int callId) {
@@ -72,7 +72,7 @@
     }
 
     /**
-     * TODO(klp): Add a confirmation callback parameter.
+     * TODO: Add a confirmation callback parameter.
      */
     @Override
     public void rejectCall(int callId, boolean rejectWithMessage, String message) {
@@ -204,7 +204,6 @@
     @Override
     public void speaker(boolean onOff) {
         try {
-            // TODO(klp): add bluetooth logic from InCallScreen.toggleSpeaker()
             PhoneUtils.turnOnSpeaker(mContext, onOff, true);
         } catch (Exception e) {
             Log.e(TAG, "Error during speaker().", e);
diff --git a/src/com/android/phone/CallHandlerServiceProxy.java b/src/com/android/phone/CallHandlerServiceProxy.java
index 1d43fe8..c6d4346 100644
--- a/src/com/android/phone/CallHandlerServiceProxy.java
+++ b/src/com/android/phone/CallHandlerServiceProxy.java
@@ -16,12 +16,14 @@
 
 package com.android.phone;
 
+import android.Manifest;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -337,7 +339,21 @@
                 final PackageManager packageManger = mContext.getPackageManager();
                 final List<ResolveInfo> services = packageManger.queryIntentServices(serviceIntent,
                         0);
-                if (services.size() == 0) {
+
+                ServiceInfo serviceInfo = null;
+
+                for (int i = 0; i < services.size(); i++) {
+                    final ResolveInfo info = services.get(i);
+                    if (info.serviceInfo != null) {
+                        if (Manifest.permission.BIND_CALL_SERVICE.equals(
+                                info.serviceInfo.permission)) {
+                            serviceInfo = info.serviceInfo;
+                            break;
+                        }
+                    }
+                }
+
+                if (serviceInfo == null) {
                     // Service not found, retry again after some delay
                     // This can happen if the service is being installed by the package manager.
                     // Between deletes and installs, bindService could get a silent service not
@@ -356,6 +372,11 @@
                     return;
                 }
 
+                // Bind to the first service that has a permission
+                // TODO: Add UI to allow us to select between services
+
+                serviceIntent.setComponent(new ComponentName(serviceInfo.packageName,
+                        serviceInfo.name));
                 if (DBG) {
                     Log.d(TAG, "binding to service " + serviceIntent);
                 }
diff --git a/src/com/android/phone/CallModeler.java b/src/com/android/phone/CallModeler.java
index f53e788..75da0be 100644
--- a/src/com/android/phone/CallModeler.java
+++ b/src/com/android/phone/CallModeler.java
@@ -70,7 +70,7 @@
  * the telephony layer. We use Connection references as identifiers for a call;
  * new reference = new call.
  *
- * TODO(klp): Create a new Call class to replace the simple call Id ints
+ * TODO: Create a new Call class to replace the simple call Id ints
  * being used currently.
  *
  * The new Call models are parcellable for transfer via the CallHandlerService
@@ -320,9 +320,6 @@
 
             mCallMap.remove(conn);
         }
-
-        // TODO(klp): Do a final check to see if there are any active calls.
-        // If there are not, totally cancel all calls
     }
 
     /**
@@ -594,7 +591,7 @@
         boolean canMute = false;
 
         final boolean supportHold = PhoneUtils.okToSupportHold(mCallManager);
-        final boolean canHold = PhoneUtils.okToHoldCall(mCallManager);
+        final boolean canHold = (supportHold ? PhoneUtils.okToHoldCall(mCallManager) : false);
         final boolean genericConf = isForConference &&
                 (connection.getCall().getPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA);
 
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index 9eaf591..0f5c6b5 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -771,7 +771,7 @@
         // There's no need to force a UI update since we update the
         // in-call notification ourselves (below), and the InCallScreen
         // listens for phone state changes itself.
-        // TODO(klp): Have BluetoothManager listen to CallModeler instead of relying on
+        // TODO: Have BluetoothManager listen to CallModeler instead of relying on
         // CallNotifier
         mBluetoothManager.updateBluetoothIndication();
 
diff --git a/src/com/android/phone/InCallScreen.java b/src/com/android/phone/InCallScreen.java
index 8b67b77..4073bbb 100644
--- a/src/com/android/phone/InCallScreen.java
+++ b/src/com/android/phone/InCallScreen.java
@@ -2685,12 +2685,6 @@
         boolean newSpeakerState = !PhoneUtils.isSpeakerOn(this);
         log("toggleSpeaker(): newSpeakerState = " + newSpeakerState);
 
-        // TODO(klp): Add bluetooth query back in for AudioRouter.
-        /*
-         if (newSpeakerState && isBluetoothAvailable() && isBluetoothAudioConnected()) {
-            disconnectBluetoothAudio();
-        }
-        */
         PhoneUtils.turnOnSpeaker(this, newSpeakerState, true);
 
         // And update the InCallTouchUi widget (since the "audio mode"
@@ -2708,16 +2702,6 @@
         PhoneUtils.setMute(newMuteState);
     }
 
-    public void toggleBluetooth() {
-        // TODO(klp) this still here to avoid compile errors until remove
-        // the UI from services/Telephony completely.
-    }
-
-    public void switchInCallAudio(InCallAudioMode newMode) {
-        // TODO(klp) this still here to avoid compile errors until remove
-        // the UI from services/Telephony completely.
-    }
-
     /**
      * Handle a click on the "Open/Close dialpad" button.
      *
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
index 1d08671..9cb2a52 100644
--- a/src/com/android/phone/InCallTouchUi.java
+++ b/src/com/android/phone/InCallTouchUi.java
@@ -868,7 +868,6 @@
         MenuItem earpieceItem = menu.findItem(R.id.audio_mode_earpiece);
         MenuItem wiredHeadsetItem = menu.findItem(R.id.audio_mode_wired_headset);
 
-        // TODO(klp): This is a compile stop-gap.  This will all be deleted
         final boolean usingHeadset = false; //mApp.isHeadsetPlugged();
 
         earpieceItem.setVisible(!usingHeadset);
@@ -938,16 +937,16 @@
 
         switch (item.getItemId()) {
             case R.id.audio_mode_speaker:
-                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.SPEAKER);
+//                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.SPEAKER);
                 break;
             case R.id.audio_mode_earpiece:
             case R.id.audio_mode_wired_headset:
                 // InCallAudioMode.EARPIECE means either the handset earpiece,
                 // or the wired headset (if connected.)
-                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.EARPIECE);
+//                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.EARPIECE);
                 break;
             case R.id.audio_mode_bluetooth:
-                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.BLUETOOTH);
+//                mInCallScreen.switchInCallAudio(InCallScreen.InCallAudioMode.BLUETOOTH);
                 break;
             default:
                 Log.wtf(LOG_TAG,
diff --git a/src/com/android/phone/RejectWithTextMessageManager.java b/src/com/android/phone/RejectWithTextMessageManager.java
index fda8f78..232de8e 100644
--- a/src/com/android/phone/RejectWithTextMessageManager.java
+++ b/src/com/android/phone/RejectWithTextMessageManager.java
@@ -250,7 +250,6 @@
             return true;
         } else {
             Log.v(TAG, "Choosing from one of the apps");
-            // TODO(klp): Add an app picker.
             final Intent intent = new Intent(Intent.ACTION_VIEW, null);
             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                     Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |