HDMICEC: Add a new validation to CEC messages

Add one more parameter to the isValid() method to indicate if the message that needs to be validated is sent or received by the device.

Add a filter that ignores received messages which have source's logical address equal to device's logical address.

Revise isValid() calls and tests affected by the change.

Edit HdmiControlServiceTest#handleCecCommand_errorParameter_returnsAbortInvalidOperand() test. Since the logical address Constants.ADDR_PLAYBACK_1 is already used by mPlaybackDeviceSpy the message's source is set to Constants.ADDR_PLAYBACK_2; otherwise HdmiCecMessageValidator#isValid() fails with a different error code than expected.

Bug: 198261021
Test: make && atest CtsHdmiCecHostTestCases
Change-Id: I274a9a2385d616784dfc891aabd8f335c32658da
(cherry picked from commit c3d3e32e50)
This commit is contained in:
Paul
2021-09-15 15:45:35 +00:00
committed by Paul Colța
parent 86170faab2
commit e96fe8f40d
5 changed files with 24 additions and 8 deletions

View File

@@ -254,7 +254,7 @@ public class HdmiCecMessageValidator {
mValidationInfo.append(opcode, new ValidationInfo(validator, addrType)); mValidationInfo.append(opcode, new ValidationInfo(validator, addrType));
} }
int isValid(HdmiCecMessage message) { int isValid(HdmiCecMessage message, boolean isMessageReceived) {
int opcode = message.getOpcode(); int opcode = message.getOpcode();
ValidationInfo info = mValidationInfo.get(opcode); ValidationInfo info = mValidationInfo.get(opcode);
if (info == null) { if (info == null) {
@@ -268,6 +268,22 @@ public class HdmiCecMessageValidator {
HdmiLogger.warning("Unexpected source: " + message); HdmiLogger.warning("Unexpected source: " + message);
return ERROR_SOURCE; return ERROR_SOURCE;
} }
if (isMessageReceived) {
// Check if the source's logical address and local device's logical
// address are the same.
for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) {
synchronized (device.mLock) {
if (message.getSource() == device.getDeviceInfo().getLogicalAddress()
&& message.getSource() != Constants.ADDR_UNREGISTERED) {
HdmiLogger.warning(
"Unexpected source: message sent from device itself, " + message);
return ERROR_SOURCE;
}
}
}
}
// Check the destination field. // Check the destination field.
if (message.getDestination() == Constants.ADDR_BROADCAST) { if (message.getDestination() == Constants.ADDR_BROADCAST) {
if ((info.addressType & DEST_BROADCAST) == 0) { if ((info.addressType & DEST_BROADCAST) == 0) {

View File

@@ -1132,7 +1132,7 @@ public class HdmiControlService extends SystemService {
@ServiceThreadOnly @ServiceThreadOnly
void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) { void sendCecCommand(HdmiCecMessage command, @Nullable SendMessageCallback callback) {
assertRunOnServiceThread(); assertRunOnServiceThread();
if (mMessageValidator.isValid(command) == HdmiCecMessageValidator.OK) { if (mMessageValidator.isValid(command, false) == HdmiCecMessageValidator.OK) {
mCecController.sendCommand(command, callback); mCecController.sendCommand(command, callback);
} else { } else {
HdmiLogger.error("Invalid message type:" + command); HdmiLogger.error("Invalid message type:" + command);
@@ -1165,7 +1165,7 @@ public class HdmiControlService extends SystemService {
@Constants.HandleMessageResult @Constants.HandleMessageResult
protected int handleCecCommand(HdmiCecMessage message) { protected int handleCecCommand(HdmiCecMessage message) {
assertRunOnServiceThread(); assertRunOnServiceThread();
int errorCode = mMessageValidator.isValid(message); int errorCode = mMessageValidator.isValid(message, true);
if (errorCode != HdmiCecMessageValidator.OK) { if (errorCode != HdmiCecMessageValidator.OK) {
// We'll not response on the messages with the invalid source or destination // We'll not response on the messages with the invalid source or destination
// or with parameter length shorter than specified in the standard. // or with parameter length shorter than specified in the standard.
@@ -3549,8 +3549,8 @@ public class HdmiControlService extends SystemService {
invokeInputChangeListener(info); invokeInputChangeListener(info);
} }
void setMhlInputChangeEnabled(boolean enabled) { void setMhlInputChangeEnabled(boolean enabled) {
mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled)); mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled));
synchronized (mLock) { synchronized (mLock) {
mMhlInputChangeEnabled = enabled; mMhlInputChangeEnabled = enabled;

View File

@@ -191,7 +191,7 @@ public class HdmiCecLocalDeviceTest {
mMessageValidator = mMessageValidator =
new HdmiCecMessageValidator(mHdmiControlService) { new HdmiCecMessageValidator(mHdmiControlService) {
@Override @Override
int isValid(HdmiCecMessage message) { int isValid(HdmiCecMessage message, boolean isMessageReceived) {
return HdmiCecMessageValidator.OK; return HdmiCecMessageValidator.OK;
} }
}; };

View File

@@ -647,6 +647,6 @@ public class HdmiCecMessageValidatorTest {
} }
private IntegerSubject assertMessageValidity(String message) { private IntegerSubject assertMessageValidity(String message) {
return assertThat(mHdmiCecMessageValidator.isValid(HdmiUtils.buildMessage(message))); return assertThat(mHdmiCecMessageValidator.isValid(HdmiUtils.buildMessage(message), false));
} }
} }

View File

@@ -793,7 +793,7 @@ public class HdmiControlServiceTest {
@Test @Test
public void handleCecCommand_errorParameter_returnsAbortInvalidOperand() { public void handleCecCommand_errorParameter_returnsAbortInvalidOperand() {
// Validity ERROR_PARAMETER. Taken from HdmiCecMessageValidatorTest#isValid_menuStatus // Validity ERROR_PARAMETER. Taken from HdmiCecMessageValidatorTest#isValid_menuStatus
HdmiCecMessage message = HdmiUtils.buildMessage("40:8D:03"); HdmiCecMessage message = HdmiUtils.buildMessage("80:8D:03");
assertThat(mHdmiControlServiceSpy.handleCecCommand(message)) assertThat(mHdmiControlServiceSpy.handleCecCommand(message))
.isEqualTo(Constants.ABORT_INVALID_OPERAND); .isEqualTo(Constants.ABORT_INVALID_OPERAND);