Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5985c85b authored by Shraddha Basantwani's avatar Shraddha Basantwani
Browse files

CEC : Add ASCII validator for CEC messages

Test: atest HdmiCecMessageValidatorTest
Bug: 170811408
Change-Id: Ie74822a660e1b360d694629b90497b0a6f5ddcb1
parent 8fafabfe
Loading
Loading
Loading
Loading
+51 −2
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ public class HdmiCecMessageValidator {
        FixedLengthValidator oneByteValidator = new FixedLengthValidator(1);
        addValidationInfo(Constants.MESSAGE_CEC_VERSION, oneByteValidator, DEST_DIRECT);
        addValidationInfo(Constants.MESSAGE_SET_MENU_LANGUAGE,
                new FixedLengthValidator(3), DEST_BROADCAST);
                new AsciiValidator(3), DEST_BROADCAST);

        // TODO: Handle messages for the Deck Control.

@@ -149,7 +149,7 @@ public class HdmiCecMessageValidator {

        // Messages for the OSD.
        addValidationInfo(Constants.MESSAGE_SET_OSD_STRING, maxLengthValidator, DEST_DIRECT);
        addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, maxLengthValidator, DEST_DIRECT);
        addValidationInfo(Constants.MESSAGE_SET_OSD_NAME, new AsciiValidator(1, 14), DEST_DIRECT);

        // Messages for the Device Menu Control.
        addValidationInfo(Constants.MESSAGE_MENU_REQUEST, oneByteValidator, DEST_DIRECT);
@@ -299,6 +299,25 @@ public class HdmiCecMessageValidator {
        return (value >= min && value <= max);
    }

    /**
     * Check if the given params has valid ASCII characters.
     * A valid ASCII character is a printable character. It should fall within range description
     * defined in CEC 1.4 Specification : Operand Descriptions (Section 17)
     *
     * @param params parameter consisting of string
     * @param offset Start offset of string
     * @param maxLength Maximum length of string to be evaluated
     * @return true if the given type is valid
     */
    private boolean isValidAsciiString(byte[] params, int offset, int maxLength) {
        for (int i = offset; i < params.length && i < maxLength; i++) {
            if (!isWithinRange(params[i], 0x20, 0x7E)) {
                return false;
            }
        }
        return true;
    }

    private class PhysicalAddressValidator implements ParameterValidator {
        @Override
        public int isValid(byte[] params) {
@@ -359,4 +378,34 @@ public class HdmiCecMessageValidator {
                            || params[0] == 0x1F);
        }
    }

    /**
     * Check if the given parameters represents printable characters.
     * A valid parameter should lie within the range description of ASCII defined in CEC 1.4
     * Specification : Operand Descriptions (Section 17)
     */
    private class AsciiValidator implements ParameterValidator {
        private final int mMinLength;
        private final int mMaxLength;

        AsciiValidator(int length) {
            mMinLength = length;
            mMaxLength = length;
        }

        AsciiValidator(int minLength, int maxLength) {
            mMinLength = minLength;
            mMaxLength = maxLength;
        }

        @Override
        public int isValid(byte[] params) {
            // If the length is longer than expected, we assume it's OK since the parameter can be
            // extended in the future version.
            if (params.length < mMinLength) {
                return ERROR_PARAMETER_SHORT;
            }
            return toErrorCode(isValidAsciiString(params, 0, mMaxLength));
        }
    }
}
+23 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.hdmi;

import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_DESTINATION;
import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER;
import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_PARAMETER_SHORT;
import static com.android.server.hdmi.HdmiCecMessageValidator.ERROR_SOURCE;
import static com.android.server.hdmi.HdmiCecMessageValidator.OK;
@@ -71,6 +72,28 @@ public class HdmiCecMessageValidatorTest {
        assertMessageValidity("04:90").isEqualTo(ERROR_PARAMETER_SHORT);
    }

    @Test
    public void isValid_setMenuLanguage() {
        assertMessageValidity("4F:32:53:50:41").isEqualTo(OK);
        assertMessageValidity("0F:32:45:4E:47:8C:49:D3:48").isEqualTo(OK);

        assertMessageValidity("40:32:53:50:41").isEqualTo(ERROR_DESTINATION);
        assertMessageValidity("F0:32").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("4F:32:45:55").isEqualTo(ERROR_PARAMETER_SHORT);
        assertMessageValidity("4F:32:19:7F:83").isEqualTo(ERROR_PARAMETER);
    }

    @Test
    public void isValid_setOsdName() {
        assertMessageValidity("40:47:4C:69:76:69:6E:67:52:6F:6F:6D:54:56").isEqualTo(OK);
        assertMessageValidity("40:47:54:56").isEqualTo(OK);

        assertMessageValidity("4F:47:54:56").isEqualTo(ERROR_DESTINATION);
        assertMessageValidity("F0:47:54:56").isEqualTo(ERROR_SOURCE);
        assertMessageValidity("40:47").isEqualTo(ERROR_PARAMETER_SHORT);
        assertMessageValidity("40:47:4C:69:7F").isEqualTo(ERROR_PARAMETER);
    }

    private IntegerSubject assertMessageValidity(String message) {
        return assertThat(mHdmiCecMessageValidator.isValid(buildMessage(message)));
    }