CEC: Revisit the behavior of HDMI_SYSTEM_AUDIO_ENABLED
Currently the system setting, HDMI_SYSTEM_AUDIO_ENABLED, is used to
store the latest system audio mode status so that TV can keep this
status over reboot. But because the name is a little confusing and the
behavior isn't intuitive, it is likely to use this in a wrong way.
This change renames this setting to HDMI_SYSTEM_AUDIO_CONTROL_ENABLED
and tweak the purpose of it. Now, it will act more like a switch for
System Audio Control feature, so user can disable or enable this feature
entirely. With this way, implementation of audio output option will
also become easier.
Bug: 31449672
Test: Tested on archer
Change-Id: Ice8717135272d4b86665a3452bfe7527c0d6c08b
(cherry picked from commit 7b7aa8fb31ccf0cd3f36162a52f080263dd89e77)
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index d81e092..a50ec49f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -72,7 +72,8 @@
@ServiceThreadOnly
private boolean mArcEstablished = false;
- // Stores whether ARC feature is enabled per port. True by default for all the ARC-enabled ports.
+ // Stores whether ARC feature is enabled per port.
+ // True by default for all the ARC-enabled ports.
private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
// Whether System audio mode is activated or not.
@@ -80,6 +81,10 @@
@GuardedBy("mLock")
private boolean mSystemAudioActivated = false;
+ // Whether the System Audio Control feature is enabled or not. True by default.
+ @GuardedBy("mLock")
+ private boolean mSystemAudioControlFeatureEnabled;
+
// The previous port id (input) before switching to the new one. This is remembered in order to
// be able to switch to it upon receiving <Inactive Source> from currently active source.
// This remains valid only when the active source was switched via one touch play operation
@@ -186,6 +191,8 @@
mAutoDeviceOff = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
true);
mAutoWakeup = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED, true);
+ mSystemAudioControlFeatureEnabled =
+ mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);
mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
}
@@ -778,14 +785,11 @@
addAndStartAction(new HotplugDetectionAction(HdmiCecLocalDeviceTv.this));
addAndStartAction(new PowerStatusMonitorAction(HdmiCecLocalDeviceTv.this));
- // If there is AVR, initiate System Audio Auto initiation action,
- // which turns on and off system audio according to last system
- // audio setting.
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr != null) {
onNewAvrAdded(avr);
} else {
- setSystemAudioMode(false, true);
+ setSystemAudioMode(false);
}
}
});
@@ -818,13 +822,13 @@
void changeSystemAudioMode(boolean enabled, IHdmiControlCallback callback) {
assertRunOnServiceThread();
if (!mService.isControlEnabled() || hasAction(DeviceDiscoveryAction.class)) {
- setSystemAudioMode(false, true);
+ setSystemAudioMode(false);
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr == null) {
- setSystemAudioMode(false, true);
+ setSystemAudioMode(false);
invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return;
}
@@ -834,12 +838,13 @@
}
// # Seq 25
- void setSystemAudioMode(boolean on, boolean updateSetting) {
- HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
-
- if (updateSetting) {
- mService.writeBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, on);
+ void setSystemAudioMode(boolean on) {
+ if (!isSystemAudioControlFeatureEnabled() && on) {
+ HdmiLogger.debug("Cannot turn on system audio mode "
+ + "because the System Audio Control feature is disabled.");
+ return;
}
+ HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
updateAudioManagerForSystemAudio(on);
synchronized (mLock) {
if (mSystemAudioActivated != on) {
@@ -863,8 +868,21 @@
}
}
- boolean getSystemAudioModeSetting() {
- return mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, false);
+ @ServiceThreadOnly
+ void setSystemAudioControlFeatureEnabled(boolean enabled) {
+ assertRunOnServiceThread();
+ synchronized (mLock) {
+ mSystemAudioControlFeatureEnabled = enabled;
+ }
+ if (hasSystemAudioDevice()) {
+ changeSystemAudioMode(enabled, null);
+ }
+ }
+
+ boolean isSystemAudioControlFeatureEnabled() {
+ synchronized (mLock) {
+ return mSystemAudioControlFeatureEnabled;
+ }
}
/**
@@ -1112,6 +1130,7 @@
@ServiceThreadOnly
protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
assertRunOnServiceThread();
+ boolean systemAudioStatus = HdmiUtils.parseCommandParamSystemAudioStatus(message);
if (!isMessageForSystemAudio(message)) {
if (getAvrDeviceInfo() == null) {
// AVR may not have been discovered yet. Delay the message processing.
@@ -1121,10 +1140,15 @@
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
}
return true;
+ } else if (systemAudioStatus && !isSystemAudioControlFeatureEnabled()) {
+ HdmiLogger.debug("Ignoring <Set System Audio Mode> message "
+ + "because the System Audio Control feature is disabled: %s", message);
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
+ return true;
}
removeAction(SystemAudioAutoInitiationAction.class);
SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this,
- message.getSource(), HdmiUtils.parseCommandParamSystemAudioStatus(message), null);
+ message.getSource(), systemAudioStatus, null);
addAndStartAction(action);
return true;
}
@@ -1138,7 +1162,7 @@
// Ignore this message.
return true;
}
- setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message), true);
+ setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message));
return true;
}
@@ -1882,6 +1906,7 @@
pw.println("mArcFeatureEnabled: " + mArcFeatureEnabled);
pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("mSystemAudioMute: " + mSystemAudioMute);
+ pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
pw.println("mAutoDeviceOff: " + mAutoDeviceOff);
pw.println("mAutoWakeup: " + mAutoWakeup);
pw.println("mSkipRoutingControl: " + mSkipRoutingControl);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 89b10ac..6864e1e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -486,7 +486,7 @@
Global.HDMI_CONTROL_ENABLED,
Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
- Global.HDMI_SYSTEM_AUDIO_ENABLED,
+ Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Global.MHL_INPUT_SWITCHING_ENABLED,
Global.MHL_POWER_CHARGE_ENABLED
};
@@ -525,9 +525,9 @@
}
// No need to propagate to HAL.
break;
- case Global.HDMI_SYSTEM_AUDIO_ENABLED:
- if (isTvDeviceEnabled() && tv().isSystemAudioActivated() != enabled) {
- tv().changeSystemAudioMode(enabled, null);
+ case Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED:
+ if (isTvDeviceEnabled()) {
+ tv().setSystemAudioControlFeatureEnabled(enabled);
}
break;
case Global.MHL_INPUT_SWITCHING_ENABLED:
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index e1bcd99..7670dcc 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -262,8 +262,7 @@
return;
}
- // Turn off system audio mode and update settings.
- tv().setSystemAudioMode(false, true);
+ tv().setSystemAudioMode(false);
if (tv().isArcEstablished()) {
tv().enableAudioReturnChannel(false);
addAndStartAction(new RequestArcTerminationAction(localDevice(), address));
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
index af1a85d..449b208 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAction.java
@@ -133,7 +133,7 @@
}
protected void setSystemAudioMode(boolean mode) {
- tv().setSystemAudioMode(mode, true);
+ tv().setSystemAudioMode(mode);
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index 01063b7..d347a91 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -50,7 +50,7 @@
@Override
public void onSendCompleted(int error) {
if (error != SendMessageResult.SUCCESS) {
- tv().setSystemAudioMode(false, true);
+ tv().setSystemAudioMode(false);
finish();
}
}
@@ -71,18 +71,24 @@
return false;
}
- private void handleSystemAudioModeStatusMessage(boolean isSystemAudioModeOn) {
+ private void handleSystemAudioModeStatusMessage(boolean currentSystemAudioMode) {
if (!canChangeSystemAudio()) {
HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
finish();
return;
}
- boolean systemAudioModeSetting = tv().getSystemAudioModeSetting();
- if (systemAudioModeSetting && !isSystemAudioModeOn) {
- addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, systemAudioModeSetting, null));
+ // If System Audio Control feature is enabled, turn on system audio mode when new AVR is
+ // detected. Otherwise, turn off system audio mode.
+ boolean targetSystemAudioMode = tv().isSystemAudioControlFeatureEnabled();
+ if (currentSystemAudioMode != targetSystemAudioMode) {
+ // Start System Audio Control feature actions only if necessary.
+ addAndStartAction(
+ new SystemAudioActionFromTv(tv(), mAvrAddress, targetSystemAudioMode, null));
} else {
- tv().setSystemAudioMode(isSystemAudioModeOn, true);
+ // If AVR already has correct system audio mode, update target system audio mode
+ // immediately rather than starting feature action.
+ tv().setSystemAudioMode(targetSystemAudioMode);
}
finish();
}
@@ -101,13 +107,15 @@
}
private void handleSystemAudioModeStatusTimeout() {
- if (tv().getSystemAudioModeSetting()) {
- if (canChangeSystemAudio()) {
- addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
- }
- } else {
- tv().setSystemAudioMode(false, true);
+ if (!canChangeSystemAudio()) {
+ HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
+ finish();
+ return;
}
+ // If we can't get the current system audio mode status, just try to turn on/off system
+ // audio mode according to the system audio control setting.
+ addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress,
+ tv().isSystemAudioControlFeatureEnabled(), null));
finish();
}