Merge "Disable absolute volume behavior on standby" into main
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 64abb81..81204ef 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 @@
      */
     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 29303aa..6157402 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceSource.java
@@ -308,7 +308,6 @@
     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 5831b29..1cd267d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1336,7 +1336,6 @@
         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 9253706..eaf754d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -3793,6 +3793,11 @@
                 }
             }
         });
+
+        // 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() {
@@ -4446,10 +4451,11 @@
      * 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
@@ -4465,10 +4471,16 @@
             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()) {
@@ -4485,7 +4497,7 @@
         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 =
@@ -4493,7 +4505,7 @@
         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;
 
@@ -4509,7 +4521,7 @@
             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) {
@@ -4556,6 +4568,8 @@
      * 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) {
@@ -4597,12 +4611,14 @@
         // 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 a63d01b..e7da26e 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 @@
     }
 
     @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();