Merge tag 'android-6.0.1_r3' of https://android.googlesource.com/platform/packages/services/Telecomm into c6

Android 6.0.1 release 3
diff --git a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
index 678ad94..b2089b7 100644
--- a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
+++ b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
@@ -1203,13 +1203,13 @@
             case CallState.NEW:
             case CallState.ABORTED:
             case CallState.DISCONNECTED:
-            case CallState.CONNECTING:
-            case CallState.SELECT_PHONE_ACCOUNT:
                 return CALL_STATE_IDLE;
 
             case CallState.ACTIVE:
                 return CALL_STATE_ACTIVE;
 
+            case CallState.CONNECTING:
+            case CallState.SELECT_PHONE_ACCOUNT:
             case CallState.DIALING:
                 // Yes, this is correctly returning ALERTING.
                 // "Dialing" for BT means that we have sent information to the service provider
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 86129ce..9df010f 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -16,11 +16,19 @@
 
 package com.android.server.telecom;
 
+import android.app.ActivityManagerNative;
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.media.AudioManager;
+import android.media.IAudioService;
+import android.os.Binder;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.telecom.CallAudioState;
 
 import com.android.internal.util.IndentingPrintWriter;
@@ -86,9 +94,27 @@
                 case MSG_AUDIO_MANAGER_SET_MICROPHONE_MUTE: {
                     boolean mute = (msg.arg1 != 0);
                     if (mute != mAudioManager.isMicrophoneMute()) {
-                        Log.i(this, "changing microphone mute state to: %b", mute);
-                        mAudioManager.setMicrophoneMute(mute);
+                        IAudioService audio = getAudioService();
+                        Log.i(this, "changing microphone mute state to: %b [serviceIsNull=%b]",
+                                mute, audio == null);
+                        if (audio != null) {
+                            try {
+                                // We use the audio service directly here so that we can specify
+                                // the current user. Telecom runs in the system_server process which
+                                // may run as a separate user from the foreground user. If we
+                                // used AudioManager directly, we would change mute for the system's
+                                // user and not the current foreground, which we want to avoid.
+                                audio.setMicrophoneMute(
+                                        mute, mContext.getOpPackageName(), getCurrentUserId());
+
+                            } catch (RemoteException e) {
+                                Log.e(this, e, "Remote exception while toggling mute.");
+                            }
+                            // TODO: Check microphone state after attempting to set to ensure that
+                            // our state corroborates AudioManager's state.
+                        }
                     }
+
                     break;
                 }
                 case MSG_AUDIO_MANAGER_REQUEST_AUDIO_FOCUS_FOR_CALL: {
@@ -701,6 +727,23 @@
         return mAudioFocusStreamType != STREAM_NONE;
     }
 
+    private IAudioService getAudioService() {
+        return IAudioService.Stub.asInterface(ServiceManager.getService(Context.AUDIO_SERVICE));
+    }
+
+    private int getCurrentUserId() {
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            UserInfo currentUser = ActivityManagerNative.getDefault().getCurrentUser();
+            return currentUser.id;
+        } catch (RemoteException e) {
+            // Activity manager not running, nothing we can do assume user 0.
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        return UserHandle.USER_OWNER;
+    }
+
     /**
      * Translates an {@link AudioManager} stream type to a human-readable string description.
      *
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 6a788de..178a4ab 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -228,7 +228,7 @@
                             .getAllPhoneAccounts();
                     List<PhoneAccount> profilePhoneAccounts = new ArrayList<>(
                             allPhoneAccounts.size());
-                    for (PhoneAccount phoneAccount : profilePhoneAccounts) {
+                    for (PhoneAccount phoneAccount : allPhoneAccounts) {
                         if (isVisibleToCaller(phoneAccount)) {
                             profilePhoneAccounts.add(phoneAccount);
                         }
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index ba97304..b4392ae 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -204,9 +204,11 @@
                         mContext.getString(R.string.notification_missedCall_call_back),
                         createCallBackPendingIntent(handleUri));
 
-                builder.addAction(R.drawable.ic_message_24dp,
-                        mContext.getString(R.string.notification_missedCall_message),
-                        createSendSmsFromNotificationPendingIntent(handleUri));
+                if (canRespondViaSms(call)) {
+                    builder.addAction(R.drawable.ic_message_24dp,
+                            mContext.getString(R.string.notification_missedCall_message),
+                            createSendSmsFromNotificationPendingIntent(handleUri));
+                }
             }
 
             Bitmap photoIcon = call.getPhotoIcon();
@@ -366,6 +368,12 @@
         notification.defaults |= Notification.DEFAULT_LIGHTS;
     }
 
+    private boolean canRespondViaSms(Call call) {
+        // Only allow respond-via-sms for "tel:" calls.
+        return call.getHandle() != null &&
+                PhoneAccount.SCHEME_TEL.equals(call.getHandle().getScheme());
+    }
+
     /**
      * Adds the missed call notification on startup if there are unread missed calls.
      */