Playback device to turn on connected audio system when waking up
Bug: 167344870 Test: atest HdmiCecLocalDevicePlaybackTest Change-Id: Ia305114762a5f356347459e3da2e3d65d860d7af
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user