Merge "Support enhanced call blocking function" into pi-dev
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index ef65d8b..facbf39 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -19,7 +19,10 @@
 
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
@@ -122,6 +125,7 @@
     public static final int MUTE_ON = 3001;
     public static final int MUTE_OFF = 3002;
     public static final int TOGGLE_MUTE = 3003;
+    public static final int MUTE_EXTERNALLY_CHANGED = 3004;
 
     public static final int SWITCH_FOCUS = 4001;
 
@@ -1221,6 +1225,18 @@
         }
     }
 
+    private final BroadcastReceiver mMuteChangeReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.startSession("CARSM.mCR");
+            if (AudioManager.ACTION_MICROPHONE_MUTE_CHANGED.equals(intent.getAction())) {
+                sendInternalMessage(MUTE_EXTERNALLY_CHANGED);
+            } else {
+                Log.w(this, "Received non-mute-change intent");
+            }
+        }
+    };
+
     private final ActiveEarpieceRoute mActiveEarpieceRoute = new ActiveEarpieceRoute();
     private final ActiveHeadsetRoute mActiveHeadsetRoute = new ActiveHeadsetRoute();
     private final ActiveBluetoothRoute mActiveBluetoothRoute = new ActiveBluetoothRoute();
@@ -1337,6 +1353,8 @@
         mAvailableRoutes = mDeviceSupportedRoutes & getCurrentCallSupportedRoutes();
         mIsMuted = initState.isMuted();
         mWasOnSpeaker = false;
+        mContext.registerReceiver(mMuteChangeReceiver,
+                new IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED));
 
         mStatusBarNotifier.notifyMute(initState.isMuted());
         mStatusBarNotifier.notifySpeakerphone(initState.getRoute() == CallAudioState.ROUTE_SPEAKER);
@@ -1373,27 +1391,20 @@
      */
     @Override
     protected void unhandledMessage(Message msg) {
-        CallAudioState newCallAudioState;
         switch (msg.what) {
             case MUTE_ON:
                 setMuteOn(true);
-                newCallAudioState = new CallAudioState(mIsMuted,
-                        mCurrentCallAudioState.getRoute(),
-                        mAvailableRoutes,
-                        mCurrentCallAudioState.getActiveBluetoothDevice(),
-                        mBluetoothRouteManager.getConnectedDevices());
-                setSystemAudioState(newCallAudioState);
-                updateInternalCallAudioState();
+                updateSystemMuteState();
                 return;
             case MUTE_OFF:
                 setMuteOn(false);
-                newCallAudioState = new CallAudioState(mIsMuted,
-                        mCurrentCallAudioState.getRoute(),
-                        mAvailableRoutes,
-                        mCurrentCallAudioState.getActiveBluetoothDevice(),
-                        mBluetoothRouteManager.getConnectedDevices());
-                setSystemAudioState(newCallAudioState);
-                updateInternalCallAudioState();
+                updateSystemMuteState();
+                return;
+            case MUTE_EXTERNALLY_CHANGED:
+                mIsMuted = mAudioManager.isMicrophoneMute();
+                if (isInActiveState()) {
+                    updateSystemMuteState();
+                }
                 return;
             case TOGGLE_MUTE:
                 if (mIsMuted) {
@@ -1474,7 +1485,6 @@
                     // user and not the current foreground, which we want to avoid.
                     audio.setMicrophoneMute(
                             mute, mContext.getOpPackageName(), getCurrentUserId());
-                    mStatusBarNotifier.notifyMute(mute);
                 } catch (RemoteException e) {
                     Log.e(this, e, "Remote exception while toggling mute.");
                 }
@@ -1484,6 +1494,16 @@
         }
     }
 
+    private void updateSystemMuteState() {
+        CallAudioState newCallAudioState = new CallAudioState(mIsMuted,
+                mCurrentCallAudioState.getRoute(),
+                mAvailableRoutes,
+                mCurrentCallAudioState.getActiveBluetoothDevice(),
+                mBluetoothRouteManager.getConnectedDevices());
+        setSystemAudioState(newCallAudioState);
+        updateInternalCallAudioState();
+    }
+
     /**
      * Updates the CallAudioState object from current internal state. The result is used for
      * external communication only.
@@ -1518,7 +1538,7 @@
             Log.i(this, "setSystemAudioState: changing from %s to %s", mLastKnownCallAudioState,
                     newCallAudioState);
             if (force || !newCallAudioState.equals(mLastKnownCallAudioState)) {
-
+                mStatusBarNotifier.notifyMute(newCallAudioState.isMuted());
                 mCallsManager.onCallAudioStateChanged(mLastKnownCallAudioState, newCallAudioState);
                 updateAudioForForegroundCall(newCallAudioState);
                 mLastKnownCallAudioState = newCallAudioState;