Merge "Ignore select SystemUI tests on TV." into main
diff --git a/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java b/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java
index d764ec4..9172dc0 100644
--- a/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java
+++ b/services/core/java/com/android/server/hdmi/AbsoluteVolumeAudioStatusAction.java
@@ -32,6 +32,10 @@
private int mInitialAudioStatusRetriesLeft = 2;
+ // Flag to notify AudioService of the next audio status reported,
+ // regardless of whether the audio status changed.
+ private boolean mForceNextAudioStatusUpdate = false;
+
private static final int STATE_WAIT_FOR_INITIAL_AUDIO_STATUS = 1;
private static final int STATE_MONITOR_AUDIO_STATUS = 2;
@@ -70,6 +74,17 @@
return false;
}
+
+ /**
+ * If AVB has been enabled, send <Give Audio Status> and notify AudioService of the response.
+ */
+ void requestAndUpdateAudioStatus() {
+ if (mState == STATE_MONITOR_AUDIO_STATUS) {
+ mForceNextAudioStatusUpdate = true;
+ sendGiveAudioStatus();
+ }
+ }
+
private boolean handleReportAudioStatus(HdmiCecMessage cmd) {
if (mTargetAddress != cmd.getSource() || cmd.getParams().length == 0) {
return false;
@@ -89,12 +104,15 @@
localDevice().getService().enableAbsoluteVolumeBehavior(audioStatus);
mState = STATE_MONITOR_AUDIO_STATUS;
} else if (mState == STATE_MONITOR_AUDIO_STATUS) {
- if (audioStatus.getVolume() != mLastAudioStatus.getVolume()) {
+ if (mForceNextAudioStatusUpdate
+ || audioStatus.getVolume() != mLastAudioStatus.getVolume()) {
localDevice().getService().notifyAvbVolumeChange(audioStatus.getVolume());
}
- if (audioStatus.getMute() != mLastAudioStatus.getMute()) {
+ if (mForceNextAudioStatusUpdate
+ || audioStatus.getMute() != mLastAudioStatus.getMute()) {
localDevice().getService().notifyAvbMuteChange(audioStatus.getMute());
}
+ mForceNextAudioStatusUpdate = false;
}
mLastAudioStatus = audioStatus;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 207d38e..0671464 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -1048,6 +1048,19 @@
}
/**
+ * If AVB has been enabled, request the System Audio device's audio status and notify
+ * AudioService of its response.
+ */
+ @ServiceThreadOnly
+ void requestAndUpdateAvbAudioStatus() {
+ assertRunOnServiceThread();
+ for (AbsoluteVolumeAudioStatusAction action :
+ getActions(AbsoluteVolumeAudioStatusAction.class)) {
+ action.requestAndUpdateAudioStatus();
+ }
+ }
+
+ /**
* Determines whether {@code targetAddress} supports <Set Audio Volume Level>. Does two things
* in parallel: send <Give Features> (to get <Report Features> in response),
* and send <Set Audio Volume Level> (to see if it gets a <Feature Abort> in response).
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 5abb2b5..99fa3a3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4661,6 +4661,13 @@
// same keycode for all three mute options.
keyCode = KeyEvent.KEYCODE_VOLUME_MUTE;
break;
+ case AudioManager.ADJUST_SAME:
+ // Query the current audio status of the Audio System and display UI for it
+ // Only for TVs, because Playback devices don't display UI when using AVB
+ if (tv() != null) {
+ tv().requestAndUpdateAvbAudioStatus();
+ }
+ return;
default:
return;
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 3a20cd9..f2242bf 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -2188,11 +2188,10 @@
MediaSessionRecordImpl session = isGlobalPriorityActiveLocked() ? mGlobalPrioritySession
: mCurrentFullUserRecord.mPriorityStack.getDefaultVolumeSession();
- boolean preferSuggestedStream = false;
- if (isValidLocalStreamType(suggestedStream)
- && AudioSystem.isStreamActive(suggestedStream, 0)) {
- preferSuggestedStream = true;
- }
+ boolean preferSuggestedStream =
+ isValidLocalStreamType(suggestedStream)
+ && AudioSystem.isStreamActive(suggestedStream, 0);
+
if (session == null || preferSuggestedStream) {
if (DEBUG_KEY_EVENT) {
Log.d(TAG, "Adjusting suggestedStream=" + suggestedStream + " by " + direction
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 399655ffa..e6d326a 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
@@ -92,11 +92,11 @@
// Default Audio Status given by the System Audio device in its initial <Report Audio Status>
// that triggers AVB being enabled
- private static final AudioStatus INITIAL_SYSTEM_AUDIO_DEVICE_STATUS =
+ protected static final AudioStatus INITIAL_SYSTEM_AUDIO_DEVICE_STATUS =
new AudioStatus(50, false);
// VolumeInfo passed to AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior to enable AVB
- private static final VolumeInfo ENABLE_AVB_VOLUME_INFO =
+ protected static final VolumeInfo ENABLE_AVB_VOLUME_INFO =
new VolumeInfo.Builder(AudioManager.STREAM_MUSIC)
.setMuted(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute())
.setVolumeIndex(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume())
@@ -106,6 +106,8 @@
private static final int EMPTY_FLAGS = 0;
+ protected static final int STREAM_MUSIC_MAX_VOLUME = 25;
+
protected abstract HdmiCecLocalDevice createLocalDevice(HdmiControlService hdmiControlService);
protected abstract int getPhysicalAddress();
@@ -201,7 +203,7 @@
Collections.singletonList(getAudioOutputDevice()));
// Max volume of STREAM_MUSIC
- mAudioFramework.setStreamMaxVolume(AudioManager.STREAM_MUSIC, 25);
+ mAudioFramework.setStreamMaxVolume(AudioManager.STREAM_MUSIC, STREAM_MUSIC_MAX_VOLUME);
// Receive messages from devices to make sure they're registered in HdmiCecNetwork
mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvbTest.java
index 024e36d..86647fc 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/TvToAudioSystemAvbTest.java
@@ -321,4 +321,98 @@
getLogicalAddress(), getSystemAudioDeviceLogicalAddress(),
Constants.AUDIO_VOLUME_STATUS_UNKNOWN));
}
+
+ /**
+ * Tests that a volume adjustment command with direction ADJUST_SAME causes HdmiControlService
+ * to request the System Audio device's audio status, and notify AudioService of the
+ * audio status.
+ */
+ @Test
+ public void avbEnabled_audioDeviceVolumeAdjusted_adjustSame_updatesAudioService() {
+ enableAbsoluteVolumeBehavior();
+ mNativeWrapper.clearResultMessages();
+
+ // HdmiControlService receives a volume adjustment with direction ADJUST_SAME
+ mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeAdjusted(
+ getAudioOutputDevice(),
+ ENABLE_AVB_VOLUME_INFO,
+ AudioManager.ADJUST_SAME,
+ AudioDeviceVolumeManager.ADJUST_MODE_NORMAL
+ );
+ mTestLooper.dispatchAll();
+
+ // Device sends <Give Audio Status>
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildGiveAudioStatus(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress()));
+
+ clearInvocations(mAudioManager);
+
+ // Device receives <Report Audio Status> with a new volume and mute state
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportAudioStatus(
+ getSystemAudioDeviceLogicalAddress(),
+ getLogicalAddress(),
+ 80,
+ true));
+ mTestLooper.dispatchAll();
+
+ // HdmiControlService calls setStreamVolume and adjustStreamVolume to trigger volume UI
+ verify(mAudioManager).setStreamVolume(
+ eq(AudioManager.STREAM_MUSIC),
+ // Volume level is rescaled to the max volume of STREAM_MUSIC
+ eq(80 * STREAM_MUSIC_MAX_VOLUME / AudioStatus.MAX_VOLUME),
+ eq(AudioManager.FLAG_ABSOLUTE_VOLUME | AudioManager.FLAG_SHOW_UI));
+ verify(mAudioManager).adjustStreamVolume(
+ eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_MUTE),
+ eq(AudioManager.FLAG_ABSOLUTE_VOLUME | AudioManager.FLAG_SHOW_UI));
+ }
+
+ /**
+ * Tests that a volume adjustment command with direction ADJUST_SAME causes HdmiControlService
+ * to request the System Audio device's audio status, and notify AudioService of the
+ * audio status, even if it's unchanged from the previous one.
+ */
+ @Test
+ public void avbEnabled_audioDeviceVolumeAdjusted_adjustSame_noChange_updatesAudioService() {
+ enableAbsoluteVolumeBehavior();
+ mNativeWrapper.clearResultMessages();
+
+ // HdmiControlService receives a volume adjustment with direction ADJUST_SAME
+ mHdmiControlService.getAbsoluteVolumeChangedListener().onAudioDeviceVolumeAdjusted(
+ getAudioOutputDevice(),
+ ENABLE_AVB_VOLUME_INFO,
+ AudioManager.ADJUST_SAME,
+ AudioDeviceVolumeManager.ADJUST_MODE_NORMAL
+ );
+ mTestLooper.dispatchAll();
+
+ // Device sends <Give Audio Status>
+ assertThat(mNativeWrapper.getResultMessages()).contains(
+ HdmiCecMessageBuilder.buildGiveAudioStatus(getLogicalAddress(),
+ getSystemAudioDeviceLogicalAddress()));
+
+ clearInvocations(mAudioManager);
+
+ // Device receives <Report Audio Status> with the same volume level and mute state that
+ // as when AVB was enabled
+ mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildReportAudioStatus(
+ getSystemAudioDeviceLogicalAddress(),
+ getLogicalAddress(),
+ INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
+ INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute()));
+ mTestLooper.dispatchAll();
+
+ // HdmiControlService calls setStreamVolume and adjustStreamVolume to trigger volume UI
+ verify(mAudioManager).setStreamVolume(
+ eq(AudioManager.STREAM_MUSIC),
+ // Volume level is rescaled to the max volume of STREAM_MUSIC
+ eq(INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume()
+ * STREAM_MUSIC_MAX_VOLUME / AudioStatus.MAX_VOLUME),
+ eq(AudioManager.FLAG_ABSOLUTE_VOLUME | AudioManager.FLAG_SHOW_UI));
+ verify(mAudioManager).adjustStreamVolume(
+ eq(AudioManager.STREAM_MUSIC),
+ eq(AudioManager.ADJUST_UNMUTE),
+ eq(AudioManager.FLAG_ABSOLUTE_VOLUME | AudioManager.FLAG_SHOW_UI));
+ }
}