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

Commit 06dc4cde authored by Amy's avatar Amy Committed by shubang
Browse files

Add SystemAudioModeRequest from non TV device logic.

cherry-pick ag/4735220

Test: atest com.android.server.hdmi
Change-Id: I6fbeb7480d83446a2a26b5703123dbb81eb4de19
parent 6169956c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -279,9 +279,9 @@ final class Constants {
     * <p>True means enabling muting logic.
     * <p>False means never mute device.
     */
    // TODO(OEM): set to true to disable muting.
    // TODO(OEM): Change property to ro and set to true to disable muting.
    static final String PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE =
            "ro.hdmi.property_system_audio_mode_muting_enable";
            "persist.sys.hdmi.property_system_audio_mode_muting_enable";

    // Set to false to allow playback device to go to suspend mode even
    // when it's an active source. True by default.
+79 −10
Original line number Diff line number Diff line
@@ -333,7 +333,23 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
    protected boolean handleSystemAudioModeRequest(HdmiCecMessage message) {
        assertRunOnServiceThread();
        boolean systemAudioStatusOn = message.getParams().length != 0;
        if (!setSystemAudioMode(systemAudioStatusOn)) {
        // Check if the request comes from a non-TV device.
        // Need to check if TV supports System Audio Control
        // if non-TV device tries to turn on the feature
        if (message.getSource() != Constants.ADDR_TV) {
            if (systemAudioStatusOn) {
                handleSystemAudioModeOnFromNonTvDevice(message);
                return true;
            }
        } else {
            // If TV request the feature on
            // cache TV supporting System Audio Control
            // until Audio System loses its physical address.
            setTvSystemAudioModeSupport(true);
        }
        // If TV or Audio System does not support the feature,
        // will send abort command.
        if (!checkSupportAndSetSystemAudioMode(systemAudioStatusOn)) {
            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
            return true;
        }
@@ -348,7 +364,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
    @ServiceThreadOnly
    protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
        assertRunOnServiceThread();
        if (!setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
        if (!checkSupportAndSetSystemAudioMode(
                HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
        }
        return true;
@@ -358,7 +375,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
    @ServiceThreadOnly
    protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
        assertRunOnServiceThread();
        if (!setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
        if (!checkSupportAndSetSystemAudioMode(
                HdmiUtils.parseCommandParamSystemAudioStatus(message))) {
            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
        }
        return true;
@@ -406,7 +424,16 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
                        mAddress, message.getSource(), scaledVolume, mute));
    }

    protected boolean setSystemAudioMode(boolean newSystemAudioMode) {
    /**
     * Method to check if device support System Audio Control. If so, wake up device if necessary.
     *
     * <p> then call {@link #setSystemAudioMode(boolean)} to turn on or off System Audio Mode
     * @param newSystemAudioMode turning feature on or off. True is on. False is off.
     * @return true or false.
     *
     * <p>False when device does not support the feature. Otherwise returns true.
     */
    protected boolean checkSupportAndSetSystemAudioMode(boolean newSystemAudioMode) {
        if (!isSystemAudioControlFeatureEnabled()) {
            HdmiLogger.debug(
                    "Cannot turn "
@@ -422,6 +449,17 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
        if (newSystemAudioMode && mService.isPowerStandbyOrTransient()) {
            mService.wakeUp();
        }
        setSystemAudioMode(newSystemAudioMode);
        return true;
    }

    /**
     * Real work to turn on or off System Audio Mode.
     *
     * Use {@link #checkSupportAndSetSystemAudioMode(boolean)}
     * if trying to turn on or off the feature.
     */
    private void setSystemAudioMode(boolean newSystemAudioMode) {
        int targetPhysicalAddress = getActiveSource().physicalAddress;
        int port = getLocalPortFromPhysicalAddress(targetPhysicalAddress);
        if (newSystemAudioMode && port >= 0) {
@@ -449,7 +487,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
                mService.announceSystemAudioModeChange(newSystemAudioMode);
            }
        }
        return true;
    }

    /**
@@ -534,7 +571,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
            return;
        }

        if (setSystemAudioMode(false)) {
        if (checkSupportAndSetSystemAudioMode(false)) {
            // send <Set System Audio Mode> [“Off”]
            mService.sendCecCommand(
                    HdmiCecMessageBuilder.buildSetSystemAudioMode(
@@ -557,6 +594,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
     * <p>The result of the query may be cached until Audio device type is put in standby or loses
     * its physical address.
     */
    // TODO(amyjojo): making mTvSystemAudioModeSupport null originally and fix the logic.
    void queryTvSystemAudioModeSupport(TvSystemAudioModeSupportedCallback callback) {
        if (!mTvSystemAudioModeSupport) {
            addAndStartAction(new DetectTvSystemAudioModeSupportAction(this, callback));
@@ -565,6 +603,37 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDevice {
        }
    }

    /**
     * Handler of System Audio Mode Request on from non TV device
     */
    void handleSystemAudioModeOnFromNonTvDevice(HdmiCecMessage message) {
        if (!isSystemAudioControlFeatureEnabled()) {
            HdmiLogger.debug(
                    "Cannot turn on" + "system audio mode "
                            + "because the System Audio Control feature is disabled.");
            mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
            return;
        }
        // Wake up device if it is still on standby
        if (mService.isPowerStandbyOrTransient()) {
            mService.wakeUp();
        }
        // Check if TV supports System Audio Control.
        // Handle broadcasting setSystemAudioMode on or aborting message on callback.
        queryTvSystemAudioModeSupport(new TvSystemAudioModeSupportedCallback() {
            public void onResult(boolean supported) {
                if (supported) {
                    setSystemAudioMode(true);
                    mService.sendCecCommand(
                            HdmiCecMessageBuilder.buildSetSystemAudioMode(
                                    mAddress, Constants.ADDR_BROADCAST, true));
                } else {
                    mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
                }
            }
        });
    }

    void setTvSystemAudioModeSupport(boolean supported) {
        mTvSystemAudioModeSupport = supported;
    }
+6 −5
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.hdmi;

import android.hardware.tv.cec.V1_0.SendMessageResult;

import com.android.internal.annotations.VisibleForTesting;

/**
@@ -91,7 +92,7 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction {
                            mSendRequestActiveSourceRetryCount++;
                            sendRequestActiveSource();
                        } else {
                            audioSystem().setSystemAudioMode(false);
                            audioSystem().checkSupportAndSetSystemAudioMode(false);
                            finish();
                        }
                    }
@@ -106,7 +107,7 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction {
                            mSendSetSystemAudioModeRetryCount++;
                            sendSetSystemAudioMode(on, dest);
                        } else {
                            audioSystem().setSystemAudioMode(false);
                            audioSystem().checkSupportAndSetSystemAudioMode(false);
                            finish();
                        }
                    }
@@ -115,7 +116,7 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction {

    private void handleActiveSourceTimeout() {
        HdmiLogger.debug("Cannot get active source.");
        audioSystem().setSystemAudioMode(false);
        audioSystem().checkSupportAndSetSystemAudioMode(false);
        finish();
    }

@@ -123,12 +124,12 @@ public class SystemAudioInitiationActionFromAvr extends HdmiCecFeatureAction {
        audioSystem().queryTvSystemAudioModeSupport(
                supported -> {
                    if (supported) {
                        if (audioSystem().setSystemAudioMode(true)) {
                        if (audioSystem().checkSupportAndSetSystemAudioMode(true)) {
                            sendSetSystemAudioMode(true, Constants.ADDR_BROADCAST);
                        }
                        finish();
                    } else {
                        audioSystem().setSystemAudioMode(false);
                        audioSystem().checkSupportAndSetSystemAudioMode(false);
                        finish();
                    }
                });
+132 −95
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.server.hdmi;

import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
import static com.android.server.hdmi.Constants.ADDR_TUNER_1;
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.android.server.hdmi.HdmiControlService.STANDBY_SCREEN_OFF;
@@ -108,6 +109,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
                                    } else if (direction == AudioManager.ADJUST_MUTE) {
                                        mMusicMute = true;
                                    }
                                    break;
                                default:
                            }
                        }
@@ -170,7 +172,8 @@ public class HdmiCecLocalDeviceAudioSystemTest {
    @Test
    public void handleGiveSystemAudioModeStatus_originalOff() throws Exception {
        HdmiCecMessage expectedMessage =
                HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
                HdmiCecMessageBuilder.buildReportSystemAudioMode(
                        ADDR_AUDIO_SYSTEM, ADDR_TV, false);
        HdmiCecMessage messageGive =
                HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
        assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
@@ -206,7 +209,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
                        Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
                        Constants.ABORT_NOT_IN_CORRECT_MODE);

        mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(false);
        mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(false);
        assertThat(
            mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
                MESSAGE_REQUEST_SAD_LCPM))
@@ -224,7 +227,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
                        Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
                        Constants.ABORT_UNABLE_TO_DETERMINE);

        mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
        mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(true);
        assertThat(
            mHdmiCecLocalDeviceAudioSystem.handleRequestShortAudioDescriptor(
                MESSAGE_REQUEST_SAD_LCPM))
@@ -292,7 +295,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
        mHdmiCecLocalDeviceAudioSystem.setAutoDeviceOff(false);
        mHdmiCecLocalDeviceAudioSystem.setAutoTvOff(false);
        // Set system audio control on first
        mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
        mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(true);
        // Check if standby correctly turns off the feature
        mHdmiCecLocalDeviceAudioSystem.onStandby(false, STANDBY_SCREEN_OFF);
        mTestLooper.dispatchAll();
@@ -359,7 +362,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {

    @Test
    public void terminateSystemAudioMode_systemAudioModeOff() throws Exception {
        mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(false);
        mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(false);
        assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
        mMusicMute = false;
        HdmiCecMessage message =
@@ -373,7 +376,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {

    @Test
    public void terminateSystemAudioMode_systemAudioModeOn() throws Exception {
        mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
        mHdmiCecLocalDeviceAudioSystem.checkSupportAndSetSystemAudioMode(true);
        assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isTrue();
        mMusicMute = false;
        HdmiCecMessage expectedMessage =
@@ -529,4 +532,38 @@ public class HdmiCecLocalDeviceAudioSystemTest {
        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetStreamPath(message)).isTrue();
        assertThat(mHdmiCecLocalDeviceAudioSystem.getLocalActivePath()).isEqualTo(1);
    }

    public void handleSystemAudioModeRequest_fromNonTV_tVNotSupport() {
        HdmiCecMessage message =
                HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                        ADDR_TUNER_1, ADDR_AUDIO_SYSTEM,
                        mAvrPhysicalAddress, true);
        HdmiCecMessage expectedMessage =
                HdmiCecMessageBuilder.buildFeatureAbortCommand(
                        ADDR_AUDIO_SYSTEM,
                        ADDR_TUNER_1,
                        Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
                        Constants.ABORT_REFUSED);

        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message)).isTrue();
        mTestLooper.dispatchAll();
        assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
    }

    @Test
    public void handleSystemAudioModeRequest_fromNonTV_tVSupport() {
        HdmiCecMessage message =
                HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                        ADDR_TUNER_1, ADDR_AUDIO_SYSTEM,
                        mAvrPhysicalAddress, true);
        HdmiCecMessage expectedMessage =
                HdmiCecMessageBuilder.buildSetSystemAudioMode(
                        ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, true);
        mHdmiCecLocalDeviceAudioSystem.setTvSystemAudioModeSupport(true);


        assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(message)).isTrue();
        mTestLooper.dispatchAll();
        assertThat(mNativeWrapper.getOnlyResultMessage()).isEqualTo(expectedMessage);
    }
}