Revisit HDMI-CEC system audio mode in AudioService.

From recent feedback on HDMI-CEC system audio mode,
it would be unnecessary to enforce output from AudioService.
Instead, it would follow audio policy according to status
of HDMI-CEC system audio mode.
For that removed two params of setHdmiSystemAudioModeSupported
api of AudioManager.

In terms of speaker mute, it will be handled by removing speaker
from audio ouput instead of changing gain control. For that
added new force usage type, FOR_HDMI_SYSTEM_AUDIO_MODE and
new force config type, FORCE_HDMI_SYSTEM_AUDIO_ENFORCED.
This is used to notify change of system audio mode to
audio policy manager.

Bug: 16305986
Bug: 16002150

Change-Id: I5643ad093a651c951e12b567c6e11b88aa87cea2
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index c65961d..ef95c11 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2954,15 +2954,12 @@
      * Set Hdmi Cec system audio mode.
      *
      * @param on whether to be on system audio mode
-     * @param device out device type to be used for system audio mode.
-     *               Ignored if {@code on} is {@code false}
-     * @param name name of system audio device
      * @return output device type. 0 (DEVICE_NONE) if failed to set device.
      * @hide
      */
-    public int setHdmiSystemAudioSupported(boolean on, int device, String name) {
+    public int setHdmiSystemAudioSupported(boolean on) {
         try {
-            return getService().setHdmiSystemAudioSupported(on, device, name);
+            return getService().setHdmiSystemAudioSupported(on);
         } catch (RemoteException e) {
             Log.w(TAG, "Error setting system audio mode", e);
             return AudioSystem.DEVICE_NONE;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 3c42147..9d5fe23 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3822,8 +3822,7 @@
                     }
 
                     if (mHdmiTvClient != null) {
-                        setHdmiSystemAudioSupported(mHdmiSystemAudioSupported,
-                                mHdmiSystemAudioOutputDevice, "");
+                        setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
                     }
 
                     // indicate the end of reconfiguration phase to audio HAL
@@ -4804,113 +4803,25 @@
     private boolean mHdmiSystemAudioSupported = false;
     // Set only when device is tv.
     private HdmiTvClient mHdmiTvClient;
-    private int mHdmiSystemAudioOutputDevice = AudioSystem.DEVICE_NONE;
-    private int[] mSpeakerGains;
 
     @Override
-    public int setHdmiSystemAudioSupported(boolean on, int device, String name) {
+    public int setHdmiSystemAudioSupported(boolean on) {
         if (mHdmiTvClient == null) {
             Log.w(TAG, "Only Hdmi-Cec enabled TV device supports system audio mode.");
             return AudioSystem.DEVICE_NONE;
         }
 
-        if (on && !checkHdmiSystemAudioOutput(device)) {
-            return AudioSystem.DEVICE_NONE;
-        }
-
         synchronized (mHdmiTvClient) {
-            if (on) {
-                mHdmiSystemAudioOutputDevice = device;
-            }
             if (mHdmiSystemAudioSupported == on) {
                 return AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC);
             }
             mHdmiSystemAudioSupported = on;
-            updateHdmiSystemAudioVolumeLocked(on);
+            AudioSystem.setForceUse(AudioSystem.FOR_HDMI_SYSTEM_AUDIO,
+                    on ? AudioSystem.FORCE_HDMI_SYSTEM_AUDIO_ENFORCED : AudioSystem.FORCE_NONE);
         }
         return AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC);
     }
 
-    private boolean checkHdmiSystemAudioOutput(int device) {
-        if ((device & AudioSystem.DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO) == 0) {
-            Log.w(TAG, "Unsupported Hdmi-Cec system audio output:" + device);
-            return false;
-        }
-
-        int streamDevice = AudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC);
-        // If other devices except for system audio and speaker are available,
-        // fails to start system audio mode.
-        if ((streamDevice & ~AudioSystem.DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER) != 0) {
-            Log.w(TAG, "Should turn off other devices before starting system audio:"
-                    + streamDevice);
-            return false;
-        }
-        if (AudioSystem.getDeviceConnectionState(device, "") !=
-            AudioSystem.DEVICE_STATE_AVAILABLE) {
-            Log.w(TAG, "Output device is not connected:" + device);
-            return false;
-        }
-        return true;
-    }
-
-    private void updateHdmiSystemAudioVolumeLocked(boolean on) {
-        AudioDevicePort speaker = findAudioDevicePort(AudioSystem.DEVICE_OUT_SPEAKER);
-        if (speaker == null) {
-            Log.w(TAG, "Has no speaker output.");
-            return;
-        }
-
-        AudioPortConfig portConfig = speaker.activeConfig();
-        AudioGainConfig gainConfig = portConfig.gain();
-        int[] newGains;
-        // When system audio is on, backup original gains and mute all channels of speaker by
-        // setting gains to 0; otherwise, restore gains of speaker.
-        if (on) {
-            if (gainConfig == null) {
-                Log.w(TAG, "Speaker has no gain control.");
-                return;
-            }
-            // Back up original gains.
-            mSpeakerGains = Arrays.copyOf(gainConfig.values(), gainConfig.values().length);
-            // Set all gains to 0.
-            newGains = new int[gainConfig.values().length];
-        } else {
-            if (mSpeakerGains == null) {
-                Log.w(TAG, "mSpeakerGains should not be null.");
-                return;
-            }
-            newGains = Arrays.copyOf(mSpeakerGains, mSpeakerGains.length);
-        }
-
-        gainConfig = gainConfig.mGain.buildConfig(gainConfig.mode(),
-                gainConfig.channelMask(),
-                newGains,
-                gainConfig.rampDurationMs());
-
-        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        if (AudioSystem.SUCCESS !=  audioManager.setAudioPortGain(speaker, gainConfig)) {
-            Log.w(TAG, "Failed to update audio port config.");
-        }
-    }
-
-    private AudioDevicePort findAudioDevicePort(int type) {
-        ArrayList<AudioPort> devicePorts = new ArrayList<>();
-        AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int status = audioManager.listAudioDevicePorts(devicePorts);
-        if (status != AudioSystem.SUCCESS)  {
-            Log.w(TAG, "Failed to list up all audio ports");
-            return null;
-        }
-
-        for (AudioPort port : devicePorts) {
-            AudioDevicePort devicePort = (AudioDevicePort) port;
-            if (devicePort.type() == type) {
-                return devicePort;
-            }
-        }
-        return null;
-    }
-
     //==========================================================================================
     // Camera shutter sound policy.
     // config_camera_sound_forced configuration option in config.xml defines if the camera shutter
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 72367c8..8e2ca95 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -254,6 +254,7 @@
     public static final int DEVICE_OUT_HDMI_ARC = 0x40000;
     public static final int DEVICE_OUT_SPDIF = 0x80000;
     public static final int DEVICE_OUT_FM = 0x100000;
+    public static final int DEVICE_OUT_AUX_LINE = 0x200000;
 
     public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
 
@@ -278,6 +279,7 @@
                                               DEVICE_OUT_HDMI_ARC |
                                               DEVICE_OUT_SPDIF |
                                               DEVICE_OUT_FM |
+                                              DEVICE_OUT_AUX_LINE |
                                               DEVICE_OUT_DEFAULT);
     public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP |
                                                    DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
@@ -287,7 +289,7 @@
                                                   DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
     public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
                                                   DEVICE_OUT_USB_DEVICE);
-    public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_LINE |
+    public static final int DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO = (DEVICE_OUT_AUX_LINE |
                                                                 DEVICE_OUT_HDMI_ARC |
                                                                 DEVICE_OUT_SPDIF);
     public static final int DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER =
@@ -440,7 +442,8 @@
     public static final int FORCE_DIGITAL_DOCK = 9;
     public static final int FORCE_NO_BT_A2DP = 10;
     public static final int FORCE_SYSTEM_ENFORCED = 11;
-    private static final int NUM_FORCE_CONFIG = 12;
+    public static final int FORCE_HDMI_SYSTEM_AUDIO_ENFORCED = 12;
+    private static final int NUM_FORCE_CONFIG = 13;
     public static final int FORCE_DEFAULT = FORCE_NONE;
 
     // usage for setForceUse, must match AudioSystem::force_use
@@ -449,7 +452,8 @@
     public static final int FOR_RECORD = 2;
     public static final int FOR_DOCK = 3;
     public static final int FOR_SYSTEM = 4;
-    private static final int NUM_FORCE_USE = 5;
+    public static final int FOR_HDMI_SYSTEM_AUDIO = 5;
+    private static final int NUM_FORCE_USE = 6;
 
     // usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t
     public static final int SYNC_EVENT_NONE = 0;
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 4f7021e..7318660 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -201,7 +201,7 @@
 
     void disableSafeMediaVolume();
 
-    int setHdmiSystemAudioSupported(boolean on, int device, String name);
+    int setHdmiSystemAudioSupported(boolean on);
 
            boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
     oneway void unregisterAudioPolicyAsync(in IBinder cb);