diff options
| author | 2023-12-14 12:27:41 +0100 | |
|---|---|---|
| committer | 2023-12-19 11:40:15 +0100 | |
| commit | a7d5914203096cef196d6233342418fa3ffc711f (patch) | |
| tree | bc2845c2cf3b4b4e5d284fbd3d7798ea31ec5acb | |
| parent | 330a4fc26d4990c8994d559668cd2debbb270c4d (diff) | |
Disable absolute volume behavior on standby
Currently, AbsoluteVolumeAudioStatusAction is always removed on Standby,
but we do not always switch away from absolute volume behavior.
AVB is usually disabled on standby when System Audio Mode is disabled.
However, some soundbars don't do this, creating a situation where AVB is
enabled but no AbsoluteVolumeAudioStatusAction exists. This prevents
AudioService from receiving volume changes and displaying UI.
This CL fixes the issue by ensuring that AVB is always disabled when
AbsoluteVolumeAudioStatusAction is removed. It should no longer be
possible to have AVB enabled without the action existing.
Bug: 312381205
Test: atest TvToAudioSystemArcAvbTest#avbEnabled_standby_avbDisabled
Change-Id: Ib430b1f2f7a0683551d424084d1b038c2d23913f
5 files changed, 32 insertions, 11 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 64abb81d0e7a..81204ef5d7ed 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -1314,7 +1314,6 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice { */ protected void disableDevice( boolean initiatedByCec, final PendingActionClearedCallback originalCallback) { - removeAction(AbsoluteVolumeAudioStatusAction.class); removeAction(SetAudioVolumeLevelDiscoveryAction.class); removeAction(ActiveSourceAction.class); removeAction(ResendCecCommandAction.class); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java index 7e8a2cc6d835..04977e978a7b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java @@ -307,7 +307,6 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice { protected void disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback) { removeAction(OneTouchPlayAction.class); removeAction(DevicePowerStatusAction.class); - removeAction(AbsoluteVolumeAudioStatusAction.class); super.disableDevice(initiatedByCec, callback); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 168715713f8d..b07ed451bcfe 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1331,7 +1331,6 @@ public final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { removeAction(OneTouchRecordAction.class); removeAction(TimerRecordingAction.class); removeAction(NewDeviceAction.class); - removeAction(AbsoluteVolumeAudioStatusAction.class); // Remove pending actions. removeAction(RequestActiveSourceAction.class); diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index b3926fd1b5ba..967edbfcd9c6 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -3792,6 +3792,11 @@ public class HdmiControlService extends SystemService { } } }); + + // Make sure we switch away from absolute volume behavior (AVB) when entering standby. + // We do this because AVB should not be used unless AbsoluteVolumeAudioStatusAction exists, + // and the action cannot exist in standby because there are no local devices. + checkAndUpdateAbsoluteVolumeBehavior(); } boolean canGoToStandby() { @@ -4445,10 +4450,11 @@ public class HdmiControlService extends SystemService { * This allows the volume level of the System Audio device to be tracked and set by Android. * * Absolute volume behavior requires the following conditions: - * 1. If the System Audio Device is an Audio System: System Audio Mode is active - * 2. All AVB-capable audio output devices are already using full/absolute volume behavior - * 3. CEC volume is enabled - * 4. The System Audio device supports the <Set Audio Volume Level> message + * 1. The device is not in standby or transient to standby + * 2. If the System Audio Device is an Audio System: System Audio Mode is active + * 3. All AVB-capable audio output devices are already using full/absolute volume behavior + * 4. CEC volume is enabled + * 5. The System Audio device supports the <Set Audio Volume Level> message * * This method enables adjust-only absolute volume behavior on TV panels when conditions * 1, 2, and 3 are met, but condition 4 is not. This allows TVs to track the volume level of @@ -4464,10 +4470,16 @@ public class HdmiControlService extends SystemService { return; } + // Condition 1: The device is not in standby or transient to standby + if (mPowerStatusController != null && isPowerStandbyOrTransient()) { + switchToFullVolumeBehavior(); + return; + } + HdmiCecLocalDevice localCecDevice; if (isTvDevice() && tv() != null) { localCecDevice = tv(); - // Condition 1: TVs need System Audio Mode to be active + // Condition 2: TVs need System Audio Mode to be active // (Doesn't apply to Playback Devices, where if SAM isn't active, we assume the // TV is the System Audio Device instead.) if (!isSystemAudioActivated()) { @@ -4484,7 +4496,7 @@ public class HdmiControlService extends SystemService { HdmiDeviceInfo systemAudioDeviceInfo = getDeviceInfo( localCecDevice.findAudioReceiverAddress()); - // Condition 2: All AVB-capable audio outputs already use full/absolute volume behavior + // Condition 3: All AVB-capable audio outputs already use full/absolute volume behavior // We only need to check the first AVB-capable audio output because only TV panels // have more than one of them, and they always have the same volume behavior. @AudioManager.DeviceVolumeBehavior int currentVolumeBehavior = @@ -4492,7 +4504,7 @@ public class HdmiControlService extends SystemService { boolean alreadyUsingFullOrAbsoluteVolume = FULL_AND_ABSOLUTE_VOLUME_BEHAVIORS.contains(currentVolumeBehavior); - // Condition 3: CEC volume is enabled + // Condition 4: CEC volume is enabled boolean cecVolumeEnabled = getHdmiCecVolumeControl() == HdmiControlManager.VOLUME_CONTROL_ENABLED; @@ -4508,7 +4520,7 @@ public class HdmiControlService extends SystemService { return; } - // Condition 4: The System Audio device supports <Set Audio Volume Level> + // Condition 5: The System Audio device supports <Set Audio Volume Level> switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) { case DeviceFeatures.FEATURE_SUPPORTED: if (currentVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) { @@ -4555,6 +4567,8 @@ public class HdmiControlService extends SystemService { * are currently used. Removes the action for handling volume updates for these behaviors. */ private void switchToFullVolumeBehavior() { + Slog.d(TAG, "Switching to full volume behavior"); + if (playback() != null) { playback().removeAvbAudioStatusAction(); } else if (tv() != null) { @@ -4596,12 +4610,14 @@ public class HdmiControlService extends SystemService { // Otherwise, enable adjust-only AVB on TVs only. if (systemAudioDevice.getDeviceFeatures().getSetAudioVolumeLevelSupport() == DeviceFeatures.FEATURE_SUPPORTED) { + Slog.d(TAG, "Enabling absolute volume behavior"); for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) { getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeBehavior( device, volumeInfo, mServiceThreadExecutor, mAbsoluteVolumeChangedListener, true); } } else if (tv() != null) { + Slog.d(TAG, "Enabling adjust-only absolute volume behavior"); for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) { getAudioDeviceVolumeManager().setDeviceAbsoluteVolumeAdjustOnlyBehavior( device, volumeInfo, mServiceThreadExecutor, diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java index a63d01b6225a..e7da26ea38b1 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java @@ -456,6 +456,14 @@ public abstract class BaseAbsoluteVolumeBehaviorTest { } @Test + public void avbEnabled_standby_avbDisabled() { + enableAbsoluteVolumeBehavior(); + mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); + assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo( + AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL); + } + + @Test public void avbEnabled_cecVolumeDisabled_avbDisabled() { enableAbsoluteVolumeBehavior(); |