Merge "Playback device to turn on connected audio system when waking up"

This commit is contained in:
TreeHugger Robot
2020-10-26 19:09:38 +00:00
committed by Android (Google) Code Review
4 changed files with 147 additions and 13 deletions

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}