Merge "CEC Standby messages when going to sleep"
This commit is contained in:
committed by
Android (Google) Code Review
commit
6117d617e9
@@ -24,6 +24,7 @@ import android.annotation.RequiresFeature;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.annotation.StringDef;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
@@ -39,6 +40,8 @@ import android.util.Log;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.ConcurrentUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -318,6 +321,37 @@ public final class HdmiControlManager {
|
||||
/** The HdmiControlService will be disabled to standby. */
|
||||
public static final int CONTROL_STATE_CHANGED_REASON_STANDBY = 3;
|
||||
|
||||
// -- Which devices the playback device can send a <Standby> message to upon going to sleep.
|
||||
/**
|
||||
* Send <Standby> to TV only.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String SEND_STANDBY_ON_SLEEP_TO_TV = "to_tv";
|
||||
/**
|
||||
* Broadcast <Standby> to all devices in the network.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String SEND_STANDBY_ON_SLEEP_BROADCAST = "broadcast";
|
||||
/**
|
||||
* Don't send any <Standby> message.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String SEND_STANDBY_ON_SLEEP_NONE = "none";
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@StringDef({
|
||||
SEND_STANDBY_ON_SLEEP_TO_TV,
|
||||
SEND_STANDBY_ON_SLEEP_BROADCAST,
|
||||
SEND_STANDBY_ON_SLEEP_NONE
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StandbyBehavior {
|
||||
}
|
||||
|
||||
// True if we have a logical device of type playback hosted in the system.
|
||||
private final boolean mHasPlaybackDevice;
|
||||
// True if we have a logical device of type TV hosted in the system.
|
||||
|
||||
15
core/java/android/provider/Settings.java
Executable file → Normal file
15
core/java/android/provider/Settings.java
Executable file → Normal file
@@ -9793,6 +9793,21 @@ public final class Settings {
|
||||
public static final String HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED =
|
||||
"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:
|
||||
* <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>
|
||||
* </ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String HDMI_CONTROL_SEND_STANDBY_ON_SLEEP =
|
||||
"hdmi_control_send_standby_on_sleep";
|
||||
|
||||
/**
|
||||
* Whether or not media is shown automatically when bypassing as a heads up.
|
||||
* @hide
|
||||
|
||||
@@ -297,6 +297,7 @@ public class SettingsBackupTest {
|
||||
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_ENABLED,
|
||||
Settings.Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
Settings.Global.HDMI_CONTROL_VOLUME_CONTROL_ENABLED,
|
||||
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
|
||||
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
|
||||
|
||||
@@ -85,6 +85,14 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
|
||||
// The option is false by default. Update settings db as well to have the right
|
||||
// initial setting on UI.
|
||||
mService.writeBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, mAutoTvOff);
|
||||
|
||||
// Initialize settings database with System Property value. This will be the initial
|
||||
// setting on the UI. If no System Property is set, the option is set to to_tv by default.
|
||||
mService.writeStringSetting(Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
mService.readStringSetting(Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiProperties.send_standby_on_sleep().orElse(
|
||||
HdmiProperties.send_standby_on_sleep_values.TO_TV).name()
|
||||
.toLowerCase()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,8 +196,26 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
|
||||
}
|
||||
switch (standbyAction) {
|
||||
case HdmiControlService.STANDBY_SCREEN_OFF:
|
||||
mService.sendCecCommand(
|
||||
HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV));
|
||||
// Get latest setting value
|
||||
@HdmiControlManager.StandbyBehavior
|
||||
String sendStandbyOnSleep = mService.readStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiProperties.send_standby_on_sleep().orElse(
|
||||
HdmiProperties.send_standby_on_sleep_values.TO_TV).name()
|
||||
.toLowerCase());
|
||||
switch (sendStandbyOnSleep) {
|
||||
case HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV:
|
||||
mService.sendCecCommand(
|
||||
HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV));
|
||||
break;
|
||||
case HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST:
|
||||
mService.sendCecCommand(
|
||||
HdmiCecMessageBuilder.buildStandby(mAddress,
|
||||
Constants.ADDR_BROADCAST));
|
||||
break;
|
||||
case HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case HdmiControlService.STANDBY_SHUTDOWN:
|
||||
// ACTION_SHUTDOWN is taken as a signal to power off all the devices.
|
||||
|
||||
@@ -772,6 +772,11 @@ public class HdmiControlService extends SystemService {
|
||||
return content;
|
||||
}
|
||||
|
||||
void writeStringSetting(String key, String value) {
|
||||
ContentResolver cr = getContext().getContentResolver();
|
||||
Global.putString(cr, key, value);
|
||||
}
|
||||
|
||||
private void initializeCec(int initiatedBy) {
|
||||
mAddressAllocated = false;
|
||||
mCecController.setOption(OptionKey.SYSTEM_CEC_CONTROL, true);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
|
||||
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
|
||||
import static com.android.server.hdmi.Constants.ADDR_TV;
|
||||
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
|
||||
@@ -22,6 +23,7 @@ import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.os.Handler;
|
||||
import android.os.IPowerManager;
|
||||
import android.os.IThermalService;
|
||||
@@ -29,6 +31,7 @@ import android.os.Looper;
|
||||
import android.os.PowerManager;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings.Global;
|
||||
import android.sysprop.HdmiProperties;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
@@ -324,29 +327,117 @@ public class HdmiCecLocalDevicePlaybackTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_NotActiveSource() {
|
||||
public void handleOnStandby_ScreenOff_NotActiveSource_ToTv() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessage);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_ActiveSource() {
|
||||
public void handleOnStandby_ScreenOff_NotActiveSource_Broadcast() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_NotActiveSource_None() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(false);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_ActiveSource_ToTv() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_TO_TV);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessage = HdmiCecMessageBuilder.buildStandby(
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessage);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_ActiveSource_Broadcast() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_BROADCAST);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).contains(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleOnStandby_ScreenOff_ActiveSource_None() {
|
||||
mHdmiCecLocalDevicePlayback.mService.writeStringSetting(
|
||||
Global.HDMI_CONTROL_SEND_STANDBY_ON_SLEEP,
|
||||
HdmiControlManager.SEND_STANDBY_ON_SLEEP_NONE);
|
||||
mHdmiCecLocalDevicePlayback.setIsActiveSource(true);
|
||||
mHdmiCecLocalDevicePlayback.setAutoDeviceOff(true);
|
||||
mHdmiCecLocalDevicePlayback.onStandby(false, HdmiControlService.STANDBY_SCREEN_OFF);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
HdmiCecMessage standbyMessageToTv = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_TV);
|
||||
HdmiCecMessage standbyMessageBroadcast = HdmiCecMessageBuilder.buildStandby(
|
||||
mHdmiCecLocalDevicePlayback.mAddress, ADDR_BROADCAST);
|
||||
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageToTv);
|
||||
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standbyMessageBroadcast);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user