diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index e430a575a1e21..e531af24fb709 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3298,6 +3298,7 @@ package android.hardware.hdmi {
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerControlMode();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public String getPowerStateChangeOnActiveSourceLost();
method @Nullable public android.hardware.hdmi.HdmiSwitchClient getSwitchClient();
+ method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioControl();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getSystemAudioModeMuting();
method @Nullable public android.hardware.hdmi.HdmiTvClient getTvClient();
method @NonNull @RequiresPermission(android.Manifest.permission.HDMI_CEC) public int getTvSendStandbyOnSleep();
@@ -3314,6 +3315,7 @@ package android.hardware.hdmi {
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerControlMode(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setPowerStateChangeOnActiveSourceLost(@NonNull String);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setStandbyMode(boolean);
+ method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioControl(@NonNull int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setSystemAudioModeMuting(@NonNull int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvSendStandbyOnSleep(@NonNull int);
method @RequiresPermission(android.Manifest.permission.HDMI_CEC) public void setTvWakeOnOneTouchPlay(@NonNull int);
@@ -3323,6 +3325,7 @@ package android.hardware.hdmi {
field public static final String CEC_SETTING_NAME_HDMI_CEC_VERSION = "hdmi_cec_version";
field public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "power_control_mode";
field public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST = "power_state_change_on_active_source_lost";
+ field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL = "system_audio_control";
field public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING = "system_audio_mode_muting";
field public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP = "tv_send_standby_on_sleep";
field public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY = "tv_wake_on_one_touch_play";
@@ -3396,6 +3399,8 @@ package android.hardware.hdmi {
field public static final int RESULT_SUCCESS = 0; // 0x0
field public static final int RESULT_TARGET_NOT_AVAILABLE = 3; // 0x3
field public static final int RESULT_TIMEOUT = 1; // 0x1
+ field public static final int SYSTEM_AUDIO_CONTROL_DISABLED = 0; // 0x0
+ field public static final int SYSTEM_AUDIO_CONTROL_ENABLED = 1; // 0x1
field public static final int SYSTEM_AUDIO_MODE_MUTING_DISABLED = 0; // 0x0
field public static final int SYSTEM_AUDIO_MODE_MUTING_ENABLED = 1; // 0x1
field public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 3; // 0x3
diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 4c4deaa528612..985c53e9dc8e1 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -449,6 +449,31 @@ public final class HdmiControlManager {
@Retention(RetentionPolicy.SOURCE)
public @interface ActiveSourceLostBehavior {}
+ // -- Whether System Audio Control is enabled or disabled.
+ /**
+ * System Audio Control enabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int SYSTEM_AUDIO_CONTROL_ENABLED = 1;
+ /**
+ * System Audio Control disabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int SYSTEM_AUDIO_CONTROL_DISABLED = 0;
+ /**
+ * @hide
+ */
+ @IntDef(prefix = { "SYSTEM_AUDIO_CONTROL_" }, value = {
+ SYSTEM_AUDIO_CONTROL_ENABLED,
+ SYSTEM_AUDIO_CONTROL_DISABLED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SystemAudioControl {}
+
// -- Whether System Audio Mode muting is enabled or disabled.
/**
* System Audio Mode muting enabled.
@@ -744,6 +769,14 @@ public final class HdmiControlManager {
@SystemApi
public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST =
"power_state_change_on_active_source_lost";
+ /**
+ * Name of a setting deciding whether System Audio Control is enabled.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL =
+ "system_audio_control";
/**
* Name of a setting deciding whether System Audio Muting is allowed.
*
@@ -862,6 +895,7 @@ public final class HdmiControlManager {
CEC_SETTING_NAME_HDMI_CEC_VERSION,
CEC_SETTING_NAME_POWER_CONTROL_MODE,
CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+ CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
@@ -2133,6 +2167,58 @@ public final class HdmiControlManager {
}
}
+ /**
+ * Set the current status of System Audio Control.
+ *
+ *
Sets whether HDMI System Audio Control feature is enabled. If enabled,
+ * TV or Audio System will try to turn on the System Audio Mode if there's a
+ * connected CEC-enabled AV Receiver. Then an audio stream will be played on
+ * the AVR instead of TV speaker or Audio System speakers. If disabled, the
+ * System Audio Mode will never be activated.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public void setSystemAudioControl(@NonNull @SystemAudioControl int value) {
+ if (mService == null) {
+ Log.e(TAG, "HdmiControlService is not available");
+ throw new RuntimeException("HdmiControlService is not available");
+ }
+ try {
+ mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, value);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Get the current status of System Audio Control.
+ *
+ *
Reflects whether HDMI System Audio Control feature is enabled. If enabled,
+ * TV or Audio System will try to turn on the System Audio Mode if there's a
+ * connected CEC-enabled AV Receiver. Then an audio stream will be played on
+ * the AVR instead of TV speaker or Audio System speakers. If disabled, the
+ * System Audio Mode will never be activated.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ @SystemAudioControl
+ @RequiresPermission(android.Manifest.permission.HDMI_CEC)
+ public int getSystemAudioControl() {
+ if (mService == null) {
+ Log.e(TAG, "HdmiControlService is not available");
+ throw new RuntimeException("HdmiControlService is not available");
+ }
+ try {
+ return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/**
* Set the current status of System Audio Mode muting.
*
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3528b057b4a2b..6cac1c7f7fd29 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4870,6 +4870,12 @@
true
false
+ true
+ true
+ true
+ true
+ false
+
true
true
true
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fa5108d909d72..185f7730b3ee2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4307,6 +4307,12 @@
+
+
+
+
+
+
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
index ff820268dfd89..54bcc95858870 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecConfig.java
@@ -345,6 +345,16 @@ public class HdmiCecConfig {
R.bool.config_cecPowerStateChangeOnActiveSourceLostStandbyNow_allowed,
R.bool.config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default);
+ Setting systemAudioControl = registerSetting(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
+ R.bool.config_cecSystemAudioControl_userConfigurable);
+ systemAudioControl.registerValue(HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED,
+ R.bool.config_cecSystemAudioControlEnabled_allowed,
+ R.bool.config_cecSystemAudioControlEnabled_default);
+ systemAudioControl.registerValue(HdmiControlManager.SYSTEM_AUDIO_CONTROL_DISABLED,
+ R.bool.config_cecSystemAudioControlDisabled_allowed,
+ R.bool.config_cecSystemAudioControlDisabled_default);
+
Setting systemAudioModeMuting = registerSetting(
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
R.bool.config_cecSystemAudioModeMuting_userConfigurable);
@@ -507,6 +517,8 @@ public class HdmiCecConfig {
return STORAGE_GLOBAL_SETTINGS;
case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
return STORAGE_SHARED_PREFS;
+ case HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL:
+ return STORAGE_GLOBAL_SETTINGS;
case HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING:
return STORAGE_SHARED_PREFS;
case HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY:
@@ -544,6 +556,8 @@ public class HdmiCecConfig {
return Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED;
case HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST:
return setting.getName();
+ case HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL:
+ return Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED;
case HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING:
return setting.getName();
case HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY:
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 0bb128536b42b..a9fcce48b0244 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -110,8 +110,9 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
super(service, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
mRoutingControlFeatureEnabled =
mService.readBooleanSetting(Global.HDMI_CEC_SWITCH_ENABLED, false);
- mSystemAudioControlFeatureEnabled =
- mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);
+ mSystemAudioControlFeatureEnabled = mService.getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL)
+ == HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED;
}
private static final String SHORT_AUDIO_DESCRIPTOR_CONFIG_PATH = "/vendor/etc/sadConfig.xml";
@@ -857,7 +858,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
HdmiLogger.debug("[A]UpdateSystemAudio mode[on=%b] output=[%X]", on, device);
}
- void onSystemAduioControlFeatureSupportChanged(boolean enabled) {
+ void onSystemAudioControlFeatureSupportChanged(boolean enabled) {
setSystemAudioControlFeatureEnabled(enabled);
if (enabled) {
addAndStartAction(new SystemAudioInitiationActionFromAvr(this));
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index ce5bf089a1c63..a887463802e2a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -42,7 +42,6 @@ import android.media.AudioManager;
import android.media.AudioSystem;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager.TvInputCallback;
-import android.provider.Settings.Global;
import android.util.Slog;
import android.util.SparseBooleanArray;
@@ -155,8 +154,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
HdmiCecLocalDeviceTv(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_TV);
mPrevPortId = Constants.INVALID_PORT_ID;
- mSystemAudioControlFeatureEnabled =
- mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);
+ mSystemAudioControlFeatureEnabled = service.getHdmiCecConfig().getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL)
+ == HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED;
mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 9164e7c4e17b6..de60be81f604a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -618,6 +618,27 @@ public class HdmiControlService extends SystemService {
initializeCec(INITIATED_BY_ENABLE_CEC);
}
}, mServiceThreadExecutor);
+ mHdmiCecConfig.registerChangeListener(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
+ new HdmiCecConfig.SettingChangeListener() {
+ @Override
+ public void onChange(String setting) {
+ boolean enabled = mHdmiCecConfig.getIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL)
+ == HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED;
+ if (isTvDeviceEnabled()) {
+ tv().setSystemAudioControlFeatureEnabled(enabled);
+ }
+ if (isAudioSystemDevice()) {
+ if (audioSystem() == null) {
+ Slog.e(TAG, "Audio System device has not registered yet."
+ + " Can't turn system audio mode on.");
+ } else {
+ audioSystem().onSystemAudioControlFeatureSupportChanged(enabled);
+ }
+ }
+ }
+ }, mServiceThreadExecutor);
mHdmiCecConfig.registerChangeListener(
HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
new HdmiCecConfig.SettingChangeListener() {
@@ -758,7 +779,6 @@ public class HdmiControlService extends SystemService {
ContentResolver resolver = getContext().getContentResolver();
String[] settings = new String[] {
Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
- Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Global.MHL_INPUT_SWITCHING_ENABLED,
Global.MHL_POWER_CHARGE_ENABLED,
Global.HDMI_CEC_SWITCH_ENABLED,
@@ -785,19 +805,6 @@ public class HdmiControlService extends SystemService {
setHdmiCecVolumeControlEnabledInternal(getHdmiCecConfig().getIntValue(
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE));
break;
- case Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED:
- if (isTvDeviceEnabled()) {
- tv().setSystemAudioControlFeatureEnabled(enabled);
- }
- if (isAudioSystemDevice()) {
- if (audioSystem() == null) {
- Slog.e(TAG, "Audio System device has not registered yet."
- + " Can't turn system audio mode on.");
- break;
- }
- audioSystem().onSystemAduioControlFeatureSupportChanged(enabled);
- }
- break;
case Global.HDMI_CEC_SWITCH_ENABLED:
if (isAudioSystemDevice()) {
if (audioSystem() == null) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
index f82b245a12dc6..7fa6a46315bed 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeHdmiCecConfig.java
@@ -98,6 +98,17 @@ final class FakeHdmiCecConfig extends HdmiCecConfig {
doReturn(false).when(resources).getBoolean(
R.bool.config_cecPowerStateChangeOnActiveSourceLostStandbyNow_default);
+ doReturn(true).when(resources).getBoolean(
+ R.bool.config_cecSystemAudioControl_userConfigurable);
+ doReturn(true).when(resources).getBoolean(
+ R.bool.config_cecSystemAudioControlEnabled_allowed);
+ doReturn(true).when(resources).getBoolean(
+ R.bool.config_cecSystemAudioControlEnabled_default);
+ doReturn(true).when(resources).getBoolean(
+ R.bool.config_cecSystemAudioControlDisabled_allowed);
+ doReturn(false).when(resources).getBoolean(
+ R.bool.config_cecSystemAudioControlDisabled_default);
+
doReturn(true).when(resources).getBoolean(
R.bool.config_cecSystemAudioModeMuting_userConfigurable);
doReturn(true).when(resources).getBoolean(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
index 1c4e63edad552..d3287b3a57cca 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecConfigTest.java
@@ -84,6 +84,7 @@ public final class HdmiCecConfigTest {
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
@@ -105,6 +106,7 @@ public final class HdmiCecConfigTest {
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
@@ -126,6 +128,7 @@ public final class HdmiCecConfigTest {
.containsExactly(HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+ HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,