diff options
| -rw-r--r-- | services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java | 56 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java | 24 |
2 files changed, 79 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index f0fab26760c0..fe97f701e089 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -122,7 +122,6 @@ public class HdmiCecMessageValidator { addValidationInfo(Constants.MESSAGE_RECORD_STATUS, new RecordStatusInfoValidator(), DEST_DIRECT); - // TODO: Handle messages for the Timer Programming. addValidationInfo( Constants.MESSAGE_CLEAR_ANALOG_TIMER, new AnalogueTimerValidator(), DEST_DIRECT); addValidationInfo( @@ -141,6 +140,7 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_TIMER_CLEARED_STATUS, new TimerClearedStatusValidator(), DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_TIMER_STATUS, new TimerStatusValidator(), DEST_DIRECT); // Messages for the System Information. FixedLengthValidator oneByteValidator = new FixedLengthValidator(1); @@ -592,6 +592,46 @@ public class HdmiCecMessageValidator { return false; } + private boolean isValidProgrammedInfo(int programedInfo) { + return (isWithinRange(programedInfo, 0x00, 0x0B)); + } + + private boolean isValidNotProgrammedErrorInfo(int nonProgramedErrorInfo) { + return (isWithinRange(nonProgramedErrorInfo, 0x00, 0x0E)); + } + + private boolean isValidTimerStatusData(byte[] params, int offset) { + int programedIndicator = params[offset] & 0x10; + boolean durationAvailable = false; + if (programedIndicator == 0x10) { + // Programmed + int programedInfo = params[offset] & 0x0F; + if (isValidProgrammedInfo(programedInfo)) { + if (programedInfo == 0x09 || programedInfo == 0x0B) { + durationAvailable = true; + } else { + return true; + } + } + } else { + // Non programmed + int nonProgramedErrorInfo = params[offset] & 0x0F; + if (isValidNotProgrammedErrorInfo(nonProgramedErrorInfo)) { + if (nonProgramedErrorInfo == 0x0E) { + durationAvailable = true; + } else { + return true; + } + } + } + offset = offset + 1; + // Duration Available (2 bytes) + if (durationAvailable && params.length - offset >= 2) { + return (isValidDurationHours(params[offset]) && isValidMinute(params[offset + 1])); + } + return false; + } + private class PhysicalAddressValidator implements ParameterValidator { @Override public int isValid(byte[] params) { @@ -809,4 +849,18 @@ public class HdmiCecMessageValidator { return toErrorCode(isWithinRange(params[0], 0x00, 0x02) || (params[0] & 0xFF) == 0x80); } } + + /** + * Check if the given timer status data parameter is valid. A valid parameter should lie within + * the range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + */ + private class TimerStatusValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 1) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isValidTimerStatusData(params, 0)); + } + } } diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java index c84e10b44de8..553df3bafd00 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -329,6 +329,30 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:43:03").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_timerStatus() { + // Programmed - Space available + assertMessageValidity("40:35:58").isEqualTo(OK); + // Programmed - Not enough space available + assertMessageValidity("40:35:B9:32:1C:4F").isEqualTo(OK); + // Not programmed - Date out of range + assertMessageValidity("40:35:82:3B").isEqualTo(OK); + // Not programmed - Duplicate + assertMessageValidity("40:35:EE:52:0C").isEqualTo(OK); + + assertMessageValidity("4F:35:58").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:35:82").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:35").isEqualTo(ERROR_PARAMETER_SHORT); + // Programmed - Invalid programmed info + assertMessageValidity("40:35:BD").isEqualTo(ERROR_PARAMETER); + // Non programmed - Invalid not programmed error info + assertMessageValidity("40:35:DE").isEqualTo(ERROR_PARAMETER); + // Programmed - Might not be enough space available - Invalid duration hours + assertMessageValidity("40:35:BB:96:1C").isEqualTo(ERROR_PARAMETER); + // Not programmed - Duplicate - Invalid duration minutes + assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } |