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

Commit cce6307c authored by Nathalie Le Clair's avatar Nathalie Le Clair
Browse files

Playback device to turn on connected audio system when waking up

Bug: 167344870
Test: atest HdmiCecLocalDevicePlaybackTest
Change-Id: Ia305114762a5f356347459e3da2e3d65d860d7af
parent 92b3adcb
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -9914,13 +9914,19 @@ public final class Settings {
                "hdmi_control_auto_device_off_enabled";
        /**
         * Property to decide which devices the playback device can send a <Standby> message to upon
         * going to sleep. Supported values are:
         * Property to decide which devices the playback device can send a <Standby> message to
         * upon going to sleep. It additionally controls whether a playback device attempts to turn
         * on the connected Audio system when waking up. Supported values are:
         * <ul>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_TO_TV} to TV only.</li>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_BROADCAST} to all devices in the
         * network.</li>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_NONE} no <Standby> message sent.</li>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_TO_TV} Upon going to sleep, device
         * sends {@code <Standby>} to TV only. Upon waking up, device does not turn on the Audio
         * system via {@code <System Audio Mode Request>}.</li>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_BROADCAST} Upon going to sleep,
         * device sends {@code <Standby>} to all devices in the network. Upon waking up, device
         * attempts to turn on the Audio system via {@code <System Audio Mode Request>}.</li>
         * <li>{@link HdmiControlManager#SEND_STANDBY_ON_SLEEP_NONE} Upon going to sleep, device
         * does not send any {@code <Standby>} message. Upon waking up, device does not turn on the
         * Audio system via {@code <System Audio Mode Request>}.</li>
         * </ul>
         *
         * @hide
+26 −7
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
import android.hardware.hdmi.IHdmiControlCallback;
import android.os.RemoteException;
import android.provider.Settings.Global;
import android.util.Slog;

import java.util.ArrayList;
@@ -54,6 +55,8 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {

    private int mPowerStatusCounter = 0;

    private HdmiCecLocalDeviceSource mSource;

    // Factory method. Ensures arguments are valid.
    static OneTouchPlayAction create(HdmiCecLocalDeviceSource source,
            int targetAddress, IHdmiControlCallback callback) {
@@ -74,27 +77,33 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {

    @Override
    boolean start() {
        // Because only source device can create this action, it's safe to cast.
        mSource = source();
        sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
        broadcastActiveSource();
        // If the device is not an audio system itself, request the connected audio system to
        // turn on.
        if (shouldTurnOnConnectedAudioSystem()) {
            sendCommand(HdmiCecMessageBuilder.buildSystemAudioModeRequest(getSourceAddress(),
                    Constants.ADDR_AUDIO_SYSTEM, getSourcePath(), true));
        }
        queryDevicePowerStatus();
        addTimer(mState, HdmiConfig.TIMEOUT_MS);
        return true;
    }

    private void broadcastActiveSource() {
        // Because only source device can create this action, it's safe to cast.
        HdmiCecLocalDeviceSource source = source();
        source.mService.setAndBroadcastActiveSourceFromOneDeviceType(
        mSource.mService.setAndBroadcastActiveSourceFromOneDeviceType(
                mTargetAddress, getSourcePath(), "OneTouchPlayAction#broadcastActiveSource()");
        // When OneTouchPlay is called, client side should be responsible to send out the intent
        // of which internal source, for example YouTube, it would like to switch to.
        // Here we only update the active port and the active source records in the local
        // device as well as claiming Active Source.
        if (source.mService.audioSystem() != null) {
            source = source.mService.audioSystem();
        if (mSource.mService.audioSystem() != null) {
            mSource = mSource.mService.audioSystem();
        }
        source.setRoutingPort(Constants.CEC_SWITCH_HOME);
        source.setLocalActivePort(Constants.CEC_SWITCH_HOME);
        mSource.setRoutingPort(Constants.CEC_SWITCH_HOME);
        mSource.setLocalActivePort(Constants.CEC_SWITCH_HOME);
    }

    private void queryDevicePowerStatus() {
@@ -151,4 +160,14 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
            Slog.e(TAG, "Callback failed:" + e);
        }
    }

    private boolean shouldTurnOnConnectedAudioSystem() {
        HdmiControlService service = mSource.mService;
        if (service.isAudioSystemDevice()) {
            return false;
        }
        String sendStandbyOnSleep = service.readStringSetting(
                Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP, "");
        return sendStandbyOnSleep.equals(HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
    }
}
+39 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiControlCallback;
import android.media.AudioManager;
import android.os.Handler;
import android.os.IPowerManager;
@@ -834,4 +835,42 @@ public class HdmiCecLocalDeviceAudioSystemTest {
        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
        assertThat(mHdmiCecLocalDeviceAudioSystem.isActiveSource()).isFalse();
    }

    @Test
    @Ignore("b/151150320")
    public void oneTouchPlay() {
        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
            }
        });
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn_fromPlayback = HdmiCecMessageBuilder.buildTextViewOn(
                mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(), ADDR_TV);
        HdmiCecMessage activeSource_fromPlayback = HdmiCecMessageBuilder.buildActiveSource(
                mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
                SELF_PHYSICAL_ADDRESS);
        HdmiCecMessage systemAudioModeRequest_fromPlayback =
                HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                        mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress(),
                        ADDR_AUDIO_SYSTEM, SELF_PHYSICAL_ADDRESS, true);
        HdmiCecMessage textViewOn_fromAudioSystem = HdmiCecMessageBuilder.buildTextViewOn(
                mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(), ADDR_TV);
        HdmiCecMessage activeSource_fromAudioSystem = HdmiCecMessageBuilder.buildActiveSource(
                mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(),
                SELF_PHYSICAL_ADDRESS);
        HdmiCecMessage systemAudioModeRequest_fromAudioSystem =
                HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                        mHdmiCecLocalDeviceAudioSystem.getDeviceInfo().getLogicalAddress(),
                        ADDR_AUDIO_SYSTEM, SELF_PHYSICAL_ADDRESS, true);
        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn_fromPlayback);
        assertThat(mNativeWrapper.getResultMessages()).contains(activeSource_fromPlayback);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(
                systemAudioModeRequest_fromPlayback);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn_fromAudioSystem);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource_fromAudioSystem);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(
                systemAudioModeRequest_fromAudioSystem);
    }
}
+70 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.hdmi.IHdmiControlCallback;
import android.os.Handler;
import android.os.IPowerManager;
import android.os.IThermalService;
@@ -974,4 +975,73 @@ public class HdmiCecLocalDevicePlaybackTest {
        assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
        assertThat(mStandby).isFalse();
    }

    @Test
    public void oneTouchPlay_SendStandbyOnSleepToTv() {
        mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
            }
        });
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
                ADDR_TV);
        HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
                mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
        HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
        assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest);
    }

    @Test
    public void oneTouchPlay_SendStandbyOnSleepBroadcast() {
        mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
            }
        });
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
                ADDR_TV);
        HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
                mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
        HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
        assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
        assertThat(mNativeWrapper.getResultMessages()).contains(systemAudioModeRequest);
    }

    @Test
    public void oneTouchPlay_SendStandbyOnSleepNone() {
        mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
                Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
                HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
        mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
            @Override
            public void onComplete(int result) {
            }
        });
        mTestLooper.dispatchAll();

        HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
                ADDR_TV);
        HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
                mPlaybackLogicalAddress, mPlaybackPhysicalAddress);
        HdmiCecMessage systemAudioModeRequest = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                mPlaybackLogicalAddress, ADDR_AUDIO_SYSTEM, mPlaybackPhysicalAddress, true);
        assertThat(mNativeWrapper.getResultMessages()).contains(textViewOn);
        assertThat(mNativeWrapper.getResultMessages()).contains(activeSource);
        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(systemAudioModeRequest);
    }
}