Update handling of incoming CEC power key presses

Update handling of <User Control Pressed> messages with power related
operands. Power commands change the power status properly and should not
be converted to power keycodes.

This particularly changes the handling of <User Control Pressed>["Power"]
which could be converted to KEYCODE_POWER before when the device was on
when the keycode was received, causing the device to turn off. This is
no longer supported and <User Control Pressed>["Power"] will be treated
as a power on command.

Test: atest HdmiCecLocalDeviceTest
Fixes: 174452275
Change-Id: I10f6d0d235d999bd29b54ba96728c0bda9697ec5
This commit is contained in:
Marvin Ramin
2020-12-01 15:30:11 +01:00
parent a02ab70564
commit 0786ebc98e
2 changed files with 116 additions and 0 deletions

View File

@@ -623,6 +623,14 @@ abstract class HdmiCecLocalDevice {
return false;
}
if (isPowerOffOrToggleCommand(message) || isPowerOnOrToggleCommand(message)) {
// Power commands should already be handled above. Don't continue and convert the CEC
// keycode to Android keycode.
// Do not <Feature Abort> as the local device should already be in the correct power
// state.
return true;
}
final long downTime = SystemClock.uptimeMillis();
final byte[] params = message.getParams();
final int keycode = HdmiCecKeycode.cecKeycodeAndParamsToAndroidKey(params);

View File

@@ -112,6 +112,7 @@ public class HdmiCecLocalDeviceTest {
private HdmiCecMessageValidator mMessageValidator;
private static byte[] param;
private boolean mStandbyMessageReceived;
private boolean mWakeupMessageReceived;
private boolean isControlEnabled;
private int mPowerStatus;
@@ -130,10 +131,22 @@ public class HdmiCecLocalDeviceTest {
|| mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
}
@Override
boolean isPowerStandbyOrTransient() {
return mPowerStatus == HdmiControlManager.POWER_STATUS_STANDBY
|| mPowerStatus
== HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;
}
@Override
void standby() {
mStandbyMessageReceived = true;
}
@Override
void wakeUp() {
mWakeupMessageReceived = true;
}
};
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
@@ -276,4 +289,99 @@ public class HdmiCecLocalDeviceTest {
assertThat(result).isTrue();
}
@Test
public void handleUserControlPressed_power_localDeviceInStandby_shouldTurnOn() {
mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isTrue();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_power_localDeviceOn_shouldNotChangePowerStatus() {
mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isFalse();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_powerToggleFunction_localDeviceInStandby_shouldTurnOn() {
mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isTrue();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_powerToggleFunction_localDeviceOn_shouldTurnOff() {
mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isFalse();
assertThat(mStandbyMessageReceived).isTrue();
}
@Test
public void handleUserControlPressed_powerOnFunction_localDeviceInStandby_shouldTurnOn() {
mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_ON_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isTrue();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_powerOnFunction_localDeviceOn_noPowerStatusChange() {
mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_ON_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isFalse();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_powerOffFunction_localDeviceStandby_noPowerStatusChange() {
mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isFalse();
assertThat(mStandbyMessageReceived).isFalse();
}
@Test
public void handleUserControlPressed_powerOffFunction_localDeviceOn_shouldTurnOff() {
mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
boolean result = mHdmiLocalDevice.handleUserControlPressed(
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION));
assertThat(result).isTrue();
assertThat(mWakeupMessageReceived).isFalse();
assertThat(mStandbyMessageReceived).isTrue();
}
}