diff options
| -rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiControlService.java | 16 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java | 19 |
2 files changed, 31 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index c8c662387d16..d0532b995deb 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -4665,15 +4665,27 @@ public class HdmiControlService extends SystemService { public void onAudioDeviceVolumeChanged( @NonNull AudioDeviceAttributes audioDevice, @NonNull VolumeInfo volumeInfo) { + int localDeviceAddress = mLocalDevice.getDeviceInfo().getLogicalAddress(); - // Do nothing if the System Audio device does not support <Set Audio Volume Level> + // We can't send <Set Audio Volume Level> if the System Audio device doesn't support it. + // But AudioService has already updated its volume and expects us to set it. + // So the best we can do is to send <Give Audio Status>, which triggers + // <Report Audio Status>, which should update AudioService with its correct volume. if (mSystemAudioDevice.getDeviceFeatures().getSetAudioVolumeLevelSupport() != DeviceFeatures.FEATURE_SUPPORTED) { + // Update the volume tracked in AbsoluteVolumeAudioStatusAction + // so it correctly processes the next <Report Audio Status> + HdmiCecLocalDevice avbDevice = isTvDevice() ? tv() : playback(); + avbDevice.updateAvbVolume(volumeInfo.getVolumeIndex()); + // Send <Give Audio Status> + sendCecCommand(HdmiCecMessageBuilder.buildGiveAudioStatus( + localDeviceAddress, + mSystemAudioDevice.getLogicalAddress() + )); return; } // Send <Set Audio Volume Level> to notify the System Audio device of the volume change - int localDeviceAddress = mLocalDevice.getDeviceInfo().getLogicalAddress(); sendCecCommand(SetAudioVolumeLevelMessage.build( localDeviceAddress, mSystemAudioDevice.getLogicalAddress(), diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java index 9ad2652e9c63..673140390ae7 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java @@ -235,7 +235,7 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav } @Test - public void adjustOnlyAvbEnabled_audioDeviceVolumeChanged_doesNotSendSetAudioVolumeLevel() { + public void adjustOnlyAvbEnabled_audioDeviceVolumeChanged_requestsAndUpdatesAudioStatus() { enableAdjustOnlyAbsoluteVolumeBehavior(); mNativeWrapper.clearResultMessages(); @@ -250,7 +250,22 @@ public abstract class BaseTvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehav ); mTestLooper.dispatchAll(); - assertThat(mNativeWrapper.getResultMessages()).isEmpty(); + // We can't sent <Set Audio Volume Level> when using adjust-only AVB. + // Instead, we send <Give Audio Status>, to get the System Audio device's volume level. + // This ensures that we end up with a correct audio status in AudioService, even if it + // set it incorrectly because it assumed that we could send <Set Audio Volume Level> + assertThat(mNativeWrapper.getResultMessages().size()).isEqualTo(1); + assertThat(mNativeWrapper.getResultMessages()).contains( + HdmiCecMessageBuilder.buildGiveAudioStatus(getLogicalAddress(), + getSystemAudioDeviceLogicalAddress()) + ); + + // When we receive <Report Audio Status>, we notify AudioService of the volume level. + receiveReportAudioStatus(50, + true); + verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), + eq(50 * STREAM_MUSIC_MAX_VOLUME / AudioStatus.MAX_VOLUME), + anyInt()); } @Test |