Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f83f2937 authored by Yan Han's avatar Yan Han Committed by Android (Google) Code Review
Browse files

Merge "Show volume UI when adjusting volume with direction ADJUST_SAME" into main

parents 17fb49aa 9c69897f
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {

    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 @@ final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {
        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 @@ final class AbsoluteVolumeAudioStatusAction extends HdmiCecFeatureAction {
            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;

+13 −0
Original line number Diff line number Diff line
@@ -1047,6 +1047,19 @@ abstract class HdmiCecLocalDevice extends HdmiLocalDevice {
        }
    }

    /**
     * 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),
+7 −0
Original line number Diff line number Diff line
@@ -4661,6 +4661,13 @@ public class HdmiControlService extends SystemService {
                    // 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;
            }
+5 −3
Original line number Diff line number Diff line
@@ -92,11 +92,11 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {

    // 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 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {

    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 @@ public abstract class BaseAbsoluteVolumeBehaviorTest {
                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(
+94 −0
Original line number Diff line number Diff line
@@ -321,4 +321,98 @@ public class TvToAudioSystemAvbTest extends BaseAbsoluteVolumeBehaviorTest {
                        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));
    }
}