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)
This commit is contained in:
Donghyun Cho
2016-12-27 18:31:09 +09:00
parent ccdc6b82b8
commit c1fa9afbcd
9 changed files with 77 additions and 43 deletions

View File

@@ -7654,12 +7654,14 @@ public final class Settings {
public static final String HDMI_CONTROL_ENABLED = "hdmi_control_enabled";
/**
* Whether HDMI system audio is enabled. If enabled, TV internal speaker is muted,
* and the output is redirected to AV Receiver connected via
* {@Global#HDMI_SYSTEM_AUDIO_OUTPUT}.
* Whether HDMI System Audio Control feature is enabled. If enabled, TV will try to turn on
* system audio mode if there's a connected CEC-enabled AV Receiver. Then audio stream will
* be played on AVR instead of TV spaeker. If disabled, the system audio mode will never be
* activated.
* @hide
*/
public static final String HDMI_SYSTEM_AUDIO_ENABLED = "hdmi_system_audio_enabled";
public static final String HDMI_SYSTEM_AUDIO_CONTROL_ENABLED =
"hdmi_system_audio_control_enabled";
/**
* Whether TV will automatically turn on upon reception of the CEC command

View File

@@ -97,7 +97,7 @@ message GlobalSettingsProto {
SettingProto download_max_bytes_over_mobile = 52;
SettingProto download_recommended_max_bytes_over_mobile = 53;
SettingProto hdmi_control_enabled = 54;
SettingProto hdmi_system_audio_enabled = 55;
SettingProto hdmi_system_audio_control_enabled = 55;
SettingProto hdmi_control_auto_wakeup_enabled = 56;
SettingProto hdmi_control_auto_device_off_enabled = 57;
SettingProto mhl_input_switching_enabled = 58;

View File

@@ -198,7 +198,7 @@ public class SettingsBackupTest {
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
Settings.Global.HDMI_CONTROL_ENABLED,
Settings.Global.HDMI_SYSTEM_AUDIO_ENABLED,
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HTTP_PROXY,
Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY,

View File

@@ -240,8 +240,8 @@ class SettingsProtoDumpUtil {
Settings.Global.HDMI_CONTROL_ENABLED,
GlobalSettingsProto.HDMI_CONTROL_ENABLED);
dumpSetting(s, p,
Settings.Global.HDMI_SYSTEM_AUDIO_ENABLED,
GlobalSettingsProto.HDMI_SYSTEM_AUDIO_ENABLED);
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
GlobalSettingsProto.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED);
dumpSetting(s, p,
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
GlobalSettingsProto.HDMI_CONTROL_AUTO_WAKEUP_ENABLED);

View File

@@ -72,7 +72,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
// # 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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
}
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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
@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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
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 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
// Ignore this message.
return true;
}
setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message), true);
setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message));
return true;
}
@@ -1882,6 +1906,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
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);

View File

@@ -486,7 +486,7 @@ public final class HdmiControlService extends SystemService {
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 @@ public final class HdmiControlService extends SystemService {
}
// 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:

View File

@@ -262,8 +262,7 @@ final class HotplugDetectionAction extends HdmiCecFeatureAction {
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));

View File

@@ -133,7 +133,7 @@ abstract class SystemAudioAction extends HdmiCecFeatureAction {
}
protected void setSystemAudioMode(boolean mode) {
tv().setSystemAudioMode(mode, true);
tv().setSystemAudioMode(mode);
}
@Override

View File

@@ -50,7 +50,7 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
@Override
public void onSendCompleted(int error) {
if (error != SendMessageResult.SUCCESS) {
tv().setSystemAudioMode(false, true);
tv().setSystemAudioMode(false);
finish();
}
}
@@ -71,18 +71,24 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
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 @@ final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
}
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();
}