From 8398472551b0c63c09d21b8a7baffdcaca2788cc Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 2 Nov 2020 11:12:04 +0530 Subject: [PATCH 1/8] CEC : Add validator for deck control message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: I64897e9ae3f35f71dd3fb38b00b2d8e924b88b30 --- .../android/server/hdmi/HdmiCecMessageValidator.java | 2 ++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index fe97f701e0898..578b66e26b693 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -149,6 +149,8 @@ public class HdmiCecMessageValidator { new AsciiValidator(3), DEST_BROADCAST); // TODO: Handle messages for the Deck Control. + addValidationInfo( + Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT); // TODO: Handle messages for the Tuner Control. 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 553df3bafd001..e24e3f7ee053d 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -353,6 +353,17 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:35:EE:52:4A").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_deckControl() { + assertMessageValidity("40:42:01:6E").isEqualTo(OK); + assertMessageValidity("40:42:04").isEqualTo(OK); + + assertMessageValidity("4F:42:01").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:42:04").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:42").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:42:05").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From b6db9b9f15bba690bc06305f58580d20137a9454 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 2 Nov 2020 11:50:57 +0530 Subject: [PATCH 2/8] CEC : Add validator for deck status message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ifd0aa76d77cef5f8b83bc02a03ec63eb6c4f7721 --- .../android/server/hdmi/HdmiCecMessageValidator.java | 2 ++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 578b66e26b693..67e1bb5579359 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -151,6 +151,8 @@ public class HdmiCecMessageValidator { // TODO: Handle messages for the Deck Control. addValidationInfo( Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_DECK_STATUS, new OneByteRangeValidator(0x11, 0x1F), DEST_DIRECT); // TODO: Handle messages for the Tuner Control. 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 e24e3f7ee053d..67596052b4efa 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -364,6 +364,18 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:42:05").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_deckStatus() { + assertMessageValidity("40:1B:11:58").isEqualTo(OK); + assertMessageValidity("40:1B:1F").isEqualTo(OK); + + assertMessageValidity("4F:1B:11").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:1B:1F").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:1B").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:1B:10").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:1B:20").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From fd4e760c7948c1dc033a285a23928dc56736c608 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 2 Nov 2020 11:51:44 +0530 Subject: [PATCH 3/8] CEC : Add validator for give deck status message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ifce7a960af0e9ca8f3a7ee02d6a523e2368f1da0 --- .../android/server/hdmi/HdmiCecMessageValidator.java | 4 ++++ .../server/hdmi/HdmiCecMessageValidatorTest.java | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 67e1bb5579359..b00ae9c6ee8ad 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -153,6 +153,10 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_DECK_STATUS, new OneByteRangeValidator(0x11, 0x1F), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_GIVE_DECK_STATUS, + new OneByteRangeValidator(0x01, 0x03), + DEST_DIRECT); // TODO: Handle messages for the Tuner Control. 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 67596052b4efa..350ab24024704 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -376,6 +376,18 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:1B:20").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_giveDeckStatus() { + assertMessageValidity("40:1A:01:F8").isEqualTo(OK); + assertMessageValidity("40:1A:03").isEqualTo(OK); + + assertMessageValidity("4F:1A:01").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:1A:03").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:1A").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:1A:00").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:1A:04").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From 5ea0ca572ecb6633d035e2cea5427a600747e639 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 2 Nov 2020 15:10:20 +0530 Subject: [PATCH 4/8] CEC : Add validator for play message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ie81c995b418dee5f9d3682c10b1071f56b661e7a --- .../server/hdmi/HdmiCecMessageValidator.java | 21 ++++++++++++++++++- .../hdmi/HdmiCecMessageValidatorTest.java | 14 +++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index b00ae9c6ee8ad..e06a05e31152d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -148,7 +148,6 @@ public class HdmiCecMessageValidator { addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE, new AsciiValidator(3), DEST_BROADCAST); - // TODO: Handle messages for the Deck Control. addValidationInfo( Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT); addValidationInfo( @@ -157,6 +156,7 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_GIVE_DECK_STATUS, new OneByteRangeValidator(0x01, 0x03), DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_PLAY, new PlayModeValidator(), DEST_DIRECT); // TODO: Handle messages for the Tuner Control. @@ -871,4 +871,23 @@ public class HdmiCecMessageValidator { return toErrorCode(isValidTimerStatusData(params, 0)); } } + + /** + * Check if the given play mode parameter is valid. A valid parameter should lie within the + * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + */ + private class PlayModeValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 1) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isWithinRange(params[0], 0x05, 0x07) + || isWithinRange(params[0], 0x09, 0x0B) + || isWithinRange(params[0], 0x15, 0x17) + || isWithinRange(params[0], 0x19, 0x1B) + || isWithinRange(params[0], 0x24, 0x25) + || (params[0] == 0x20)); + } + } } 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 350ab24024704..6cc8db9957cdb 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -388,6 +388,20 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:1A:04").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_play() { + assertMessageValidity("40:41:16:E3").isEqualTo(OK); + assertMessageValidity("40:41:20").isEqualTo(OK); + + assertMessageValidity("4F:41:16").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:41:20").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:41").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:41:04").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:41:18").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:41:23").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:41:26").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From 9fa633abeb06607f8e59e2d0f9358e8cc49f9cea Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Mon, 2 Nov 2020 17:37:22 +0530 Subject: [PATCH 5/8] CEC : Add validator for give tuner device status message Reuse status request validator created for . Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ife9ad0433df8893dab0fbe010ef6b4626ff06784 --- .../com/android/server/hdmi/HdmiCecMessageValidator.java | 8 ++++---- .../android/server/hdmi/HdmiCecMessageValidatorTest.java | 9 ++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index e06a05e31152d..a3ae72e189614 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -148,17 +148,17 @@ public class HdmiCecMessageValidator { addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE, new AsciiValidator(3), DEST_BROADCAST); + ParameterValidator statusRequestValidator = new OneByteRangeValidator(0x01, 0x03); addValidationInfo( Constants.MESSAGE_DECK_CONTROL, new OneByteRangeValidator(0x01, 0x04), DEST_DIRECT); addValidationInfo( Constants.MESSAGE_DECK_STATUS, new OneByteRangeValidator(0x11, 0x1F), DEST_DIRECT); - addValidationInfo( - Constants.MESSAGE_GIVE_DECK_STATUS, - new OneByteRangeValidator(0x01, 0x03), - DEST_DIRECT); + addValidationInfo(Constants.MESSAGE_GIVE_DECK_STATUS, statusRequestValidator, DEST_DIRECT); addValidationInfo(Constants.MESSAGE_PLAY, new PlayModeValidator(), DEST_DIRECT); // TODO: Handle messages for the Tuner Control. + addValidationInfo( + Constants.MESSAGE_GIVE_TUNER_DEVICE_STATUS, statusRequestValidator, DEST_DIRECT); // Messages for the Vendor Specific Commands. VariableLengthValidator maxLengthValidator = new VariableLengthValidator(0, 14); 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 6cc8db9957cdb..5b31f8c186602 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -377,13 +377,20 @@ public class HdmiCecMessageValidatorTest { } @Test - public void isValid_giveDeckStatus() { + public void isValid_statusRequest() { + assertMessageValidity("40:08:01").isEqualTo(OK); + assertMessageValidity("40:08:02:5C").isEqualTo(OK); assertMessageValidity("40:1A:01:F8").isEqualTo(OK); assertMessageValidity("40:1A:03").isEqualTo(OK); + assertMessageValidity("4F:08:01").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:08:03").isEqualTo(ERROR_SOURCE); assertMessageValidity("4F:1A:01").isEqualTo(ERROR_DESTINATION); assertMessageValidity("F0:1A:03").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:08").isEqualTo(ERROR_PARAMETER_SHORT); assertMessageValidity("40:1A").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:08:00").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:08:05").isEqualTo(ERROR_PARAMETER); assertMessageValidity("40:1A:00").isEqualTo(ERROR_PARAMETER); assertMessageValidity("40:1A:04").isEqualTo(ERROR_PARAMETER); } From 525beb28e50be024bcd0570cca1ed9128a6e4b68 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Tue, 3 Nov 2020 17:49:54 +0530 Subject: [PATCH 6/8] CEC : Add validator for select analogue service message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: I540c290090a3ea48b04a678e39325aa7d419e04a --- .../server/hdmi/HdmiCecMessageValidator.java | 21 +++++++++++++++++++ .../hdmi/HdmiCecMessageValidatorTest.java | 16 ++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index a3ae72e189614..46913227ff7e2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -159,6 +159,10 @@ public class HdmiCecMessageValidator { // TODO: Handle messages for the Tuner Control. addValidationInfo( Constants.MESSAGE_GIVE_TUNER_DEVICE_STATUS, statusRequestValidator, DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SELECT_ANALOG_SERVICE, + new SelectAnalogueServiceValidator(), + DEST_DIRECT); // Messages for the Vendor Specific Commands. VariableLengthValidator maxLengthValidator = new VariableLengthValidator(0, 14); @@ -890,4 +894,21 @@ public class HdmiCecMessageValidator { || (params[0] == 0x20)); } } + + /** + * Check if the given select analogue service parameter is valid. A valid parameter should lie + * within the range description defined in CEC 1.4 Specification : Operand Descriptions + * (Section 17) + */ + private class SelectAnalogueServiceValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 4) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isValidAnalogueBroadcastType(params[0]) + && isValidAnalogueFrequency(HdmiUtils.twoBytesToInt(params, 1)) + && isValidBroadcastSystem(params[3])); + } + } } 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 5b31f8c186602..e69fa15741548 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -409,6 +409,22 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:41:26").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_selectAnalogueService() { + assertMessageValidity("40:92:00:13:0F:00:96").isEqualTo(OK); + assertMessageValidity("40:92:02:EA:60:1F").isEqualTo(OK); + + assertMessageValidity("4F:92:00:13:0F:00").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:92:02:EA:60:1F").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:92:00:13:0F").isEqualTo(ERROR_PARAMETER_SHORT); + // Invalid Analogue Broadcast type + assertMessageValidity("40:92:03:EA:60:1F").isEqualTo(ERROR_PARAMETER); + // Invalid Analogue Frequency + assertMessageValidity("40:92:00:FF:FF:00").isEqualTo(ERROR_PARAMETER); + // Invalid Broadcast system + assertMessageValidity("40:92:02:EA:60:20").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From c0cd32916c28ea9ad336e0f0113dd5dcb8a078d8 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Tue, 3 Nov 2020 18:55:47 +0530 Subject: [PATCH 7/8] CEC : Add validator for select digital service message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ia0f12e9b3c7cd18af9846b3e80e4e8215823d9b9 --- .../server/hdmi/HdmiCecMessageValidator.java | 19 ++++++++++++++ .../hdmi/HdmiCecMessageValidatorTest.java | 26 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index 46913227ff7e2..be0f26b7ff50c 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -163,6 +163,10 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_SELECT_ANALOG_SERVICE, new SelectAnalogueServiceValidator(), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_SELECT_DIGITAL_SERVICE, + new SelectDigitalServiceValidator(), + DEST_DIRECT); // Messages for the Vendor Specific Commands. VariableLengthValidator maxLengthValidator = new VariableLengthValidator(0, 14); @@ -911,4 +915,19 @@ public class HdmiCecMessageValidator { && isValidBroadcastSystem(params[3])); } } + + /** + * Check if the given select digital service parameter is valid. A valid parameter should lie + * within the range description defined in CEC 1.4 Specification : Operand Descriptions + * (Section 17) + */ + private class SelectDigitalServiceValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 4) { + return ERROR_PARAMETER_SHORT; + } + return toErrorCode(isValidDigitalServiceIdentification(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 e69fa15741548..ec7105872a5f1 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -425,6 +425,32 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:92:02:EA:60:20").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_selectDigitalService() { + assertMessageValidity("40:93:00:11:CE:90:0F:00:78").isEqualTo(OK); + assertMessageValidity("40:93:10:13:0B:34:38").isEqualTo(OK); + assertMessageValidity("40:93:9A:06:F9:D3:E6").isEqualTo(OK); + assertMessageValidity("40:93:91:09:F4:40:C8").isEqualTo(OK); + + assertMessageValidity("4F:93:00:11:CE:90:0F:00:78").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:93:10:13:0B:34:38").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:93:9A:06:F9").isEqualTo(ERROR_PARAMETER_SHORT); + // Invalid Digital Broadcast System + assertMessageValidity("40:93:14:11:CE:90:0F:00:78").isEqualTo(ERROR_PARAMETER); + // Invalid Digital Broadcast System + assertMessageValidity("40:93:A0:07:95:F1").isEqualTo(ERROR_PARAMETER); + // Insufficient data for ARIB Broadcast system + assertMessageValidity("40:93:00:11:CE:90:0F:00").isEqualTo(ERROR_PARAMETER); + // Insufficient data for ATSC Broadcast system + assertMessageValidity("40:93:10:13:0B:34").isEqualTo(ERROR_PARAMETER); + // Insufficient data for DVB Broadcast system + assertMessageValidity("40:93:18:BE:77:00:7D:01").isEqualTo(ERROR_PARAMETER); + // Invalid channel number format + assertMessageValidity("40:93:9A:10:F9:D3").isEqualTo(ERROR_PARAMETER); + // Insufficient data for 2 part channel number + assertMessageValidity("40:93:91:09:F4:40").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); } From 9ab0dd09ae0769c59ea698ae3fe9356aa988d662 Mon Sep 17 00:00:00 2001 From: Shraddha Basantwani Date: Thu, 5 Nov 2020 17:37:48 +0530 Subject: [PATCH 8/8] CEC : Add validator for user control pressed message Test: atest HdmiCecMessageValidatorTest Bug: 170811408 Change-Id: Ib7d4be7071e4b81e78f7fe19b5836d9c3caa4915 --- .../server/hdmi/HdmiCecMessageValidator.java | 133 +++++++++++++++--- .../hdmi/HdmiCecMessageValidatorTest.java | 43 ++++++ 2 files changed, 158 insertions(+), 18 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java index be0f26b7ff50c..ea2453216a598 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java @@ -192,9 +192,10 @@ public class HdmiCecMessageValidator { Constants.MESSAGE_MENU_STATUS, new OneByteRangeValidator(0x00, 0x01), DEST_DIRECT); // Messages for the Remote Control Passthrough. - // TODO: Parse the first parameter and determine if it can have the next parameter. - addValidationInfo(Constants.MESSAGE_USER_CONTROL_PRESSED, - new VariableLengthValidator(1, 2), DEST_DIRECT); + addValidationInfo( + Constants.MESSAGE_USER_CONTROL_PRESSED, + new UserControlPressedValidator(), + DEST_DIRECT); // Messages for the Power Status. addValidationInfo( @@ -530,6 +531,28 @@ public class HdmiCecMessageValidator { return (isAribDbs(value) || isAtscDbs(value) || isDvbDbs(value)); } + /** + * Check if the given value is a valid Channel Identifier. A valid value is one which falls + * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section + * 17) + * + * @param params Channel Identifier parameters + * @param offset start offset of Channel Identifier + * @return true if the Channel Identifier is valid + */ + private boolean isValidChannelIdentifier(byte[] params, int offset) { + // First 6 bits contain Channel Number Format + int channelNumberFormat = params[offset] & 0xFC; + if (channelNumberFormat == 0x04) { + // Validate it contains 1-part Channel Number data (16 bits) + return params.length - offset >= 3; + } else if (channelNumberFormat == 0x08) { + // Validate it contains Major Channel Number and Minor Channel Number (26 bits) + return params.length - offset >= 4; + } + return false; + } + /** * Check if the given value is a valid Digital Service Identification. A valid value is one * which falls within the range description defined in CEC 1.4 Specification : Operand @@ -560,15 +583,7 @@ public class HdmiCecMessageValidator { } else if (serviceIdentificationMethod == 0x80) { // Services identified by Channel if (isValidDigitalBroadcastSystem(digitalBroadcastSystem)) { - // First 6 bits contain Channel Number Format - int channelNumberFormat = params[offset] & 0xFC; - if (channelNumberFormat == 0x04) { - // Validate it contains 1-part Channel Number data (16 bits) - return params.length - offset >= 3; - } else if (channelNumberFormat == 0x08) { - // Validate it contains Major Channel Number and Minor Channel Number (26 bits) - return params.length - offset >= 4; - } + return isValidChannelIdentifier(params, offset); } } return false; @@ -648,6 +663,65 @@ public class HdmiCecMessageValidator { return false; } + /** + * Check if the given value is a valid Play mode. A valid value is one which falls within the + * range description defined in CEC 1.4 Specification : Operand Descriptions (Section 17) + * + * @param value Play mode + * @return true if the Play mode is valid + */ + private boolean isValidPlayMode(int value) { + return (isWithinRange(value, 0x05, 0x07) + || isWithinRange(value, 0x09, 0x0B) + || isWithinRange(value, 0x15, 0x17) + || isWithinRange(value, 0x19, 0x1B) + || isWithinRange(value, 0x24, 0x25) + || (value == 0x20)); + } + + /** + * Check if the given value is a valid UI Broadcast type. A valid value is one which falls + * within the range description defined in CEC 1.4 Specification : Operand Descriptions (Section + * 17) + * + * @param value UI Broadcast type + * @return true if the UI Broadcast type is valid + */ + private boolean isValidUiBroadcastType(int value) { + return ((value == 0x00) + || (value == 0x01) + || (value == 0x10) + || (value == 0x20) + || (value == 0x30) + || (value == 0x40) + || (value == 0x50) + || (value == 0x60) + || (value == 0x70) + || (value == 0x80) + || (value == 0x90) + || (value == 0x91) + || (value == 0xA0)); + } + + /** + * Check if the given value is a valid UI Sound Presenation Control. A valid value is one which + * falls within the range description defined in CEC 1.4 Specification : Operand Descriptions + * (Section 17) + * + * @param value UI Sound Presenation Control + * @return true if the UI Sound Presenation Control is valid + */ + private boolean isValidUiSoundPresenationControl(int value) { + value = value & 0xFF; + return ((value == 0x20) + || (value == 0x30) + || (value == 0x80) + || (value == 0x90) + || (value == 0xA0) + || (isWithinRange(value, 0xB1, 0xB3)) + || (isWithinRange(value, 0xC1, 0xC3))); + } + private class PhysicalAddressValidator implements ParameterValidator { @Override public int isValid(byte[] params) { @@ -890,12 +964,7 @@ public class HdmiCecMessageValidator { if (params.length < 1) { return ERROR_PARAMETER_SHORT; } - return toErrorCode(isWithinRange(params[0], 0x05, 0x07) - || isWithinRange(params[0], 0x09, 0x0B) - || isWithinRange(params[0], 0x15, 0x17) - || isWithinRange(params[0], 0x19, 0x1B) - || isWithinRange(params[0], 0x24, 0x25) - || (params[0] == 0x20)); + return toErrorCode(isValidPlayMode(params[0])); } } @@ -930,4 +999,32 @@ public class HdmiCecMessageValidator { return toErrorCode(isValidDigitalServiceIdentification(params, 0)); } } + + /** Check if the given user control press parameter is valid. */ + private class UserControlPressedValidator implements ParameterValidator { + @Override + public int isValid(byte[] params) { + if (params.length < 1) { + return ERROR_PARAMETER_SHORT; + } + if (params.length == 1) { + return OK; + } + int uiCommand = params[0]; + switch (uiCommand) { + case HdmiCecKeycode.CEC_KEYCODE_PLAY_FUNCTION: + return toErrorCode(isValidPlayMode(params[1])); + case HdmiCecKeycode.CEC_KEYCODE_TUNE_FUNCTION: + return (params.length >= 4 + ? toErrorCode(isValidChannelIdentifier(params, 1)) + : ERROR_PARAMETER_SHORT); + case HdmiCecKeycode.CEC_KEYCODE_SELECT_BROADCAST_TYPE: + return toErrorCode(isValidUiBroadcastType(params[1])); + case HdmiCecKeycode.CEC_KEYCODE_SELECT_SOUND_PRESENTATION: + return toErrorCode(isValidUiSoundPresenationControl(params[1])); + default: + return OK; + } + } + } } 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 ec7105872a5f1..63d7dbd150314 100644 --- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java +++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageValidatorTest.java @@ -451,6 +451,49 @@ public class HdmiCecMessageValidatorTest { assertMessageValidity("40:93:91:09:F4:40").isEqualTo(ERROR_PARAMETER); } + @Test + public void isValid_UserControlPressed() { + assertMessageValidity("40:44:07").isEqualTo(OK); + assertMessageValidity("40:44:52:A7").isEqualTo(OK); + + assertMessageValidity("40:44:60").isEqualTo(OK); + assertMessageValidity("40:44:60:1A").isEqualTo(OK); + + assertMessageValidity("40:44:67").isEqualTo(OK); + assertMessageValidity("40:44:67:04:00:B1").isEqualTo(OK); + assertMessageValidity("40:44:67:09:C8:72:C8").isEqualTo(OK); + + assertMessageValidity("40:44:68").isEqualTo(OK); + assertMessageValidity("40:44:68:93").isEqualTo(OK); + assertMessageValidity("40:44:69").isEqualTo(OK); + assertMessageValidity("40:44:69:7C").isEqualTo(OK); + assertMessageValidity("40:44:6A").isEqualTo(OK); + assertMessageValidity("40:44:6A:B4").isEqualTo(OK); + + assertMessageValidity("40:44:56").isEqualTo(OK); + assertMessageValidity("40:44:56:60").isEqualTo(OK); + + assertMessageValidity("40:44:57").isEqualTo(OK); + assertMessageValidity("40:44:57:A0").isEqualTo(OK); + + assertMessageValidity("4F:44:07").isEqualTo(ERROR_DESTINATION); + assertMessageValidity("F0:44:52:A7").isEqualTo(ERROR_SOURCE); + assertMessageValidity("40:44").isEqualTo(ERROR_PARAMETER_SHORT); + assertMessageValidity("40:44:67:04:B1").isEqualTo(ERROR_PARAMETER_SHORT); + // Invalid Play mode + assertMessageValidity("40:44:60:04").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:44:60:08").isEqualTo(ERROR_PARAMETER); + assertMessageValidity("40:44:60:26").isEqualTo(ERROR_PARAMETER); + // Invalid Channel Identifier - Channel number format + assertMessageValidity("40:44:67:11:8A:42").isEqualTo(ERROR_PARAMETER); + // Insufficient data for 2 - part channel number + assertMessageValidity("40:44:67:09:C8:72").isEqualTo(ERROR_PARAMETER); + // Invalid UI Broadcast type + assertMessageValidity("40:44:56:11").isEqualTo(ERROR_PARAMETER); + // Invalid UI Sound Presentation Control + assertMessageValidity("40:44:57:40").isEqualTo(ERROR_PARAMETER); + } + private IntegerSubject assertMessageValidity(String message) { return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message))); }