1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.hdmicec.cts.tv;
18 
19 import android.hdmicec.cts.BaseHdmiCecCtsTest;
20 import android.hdmicec.cts.CecMessage;
21 import android.hdmicec.cts.CecOperand;
22 import android.hdmicec.cts.HdmiCecConstants;
23 import android.hdmicec.cts.LogicalAddress;
24 
25 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
26 
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.RuleChain;
30 import org.junit.runner.RunWith;
31 
32 /** HDMI CEC 2.0 general protocol tests */
33 @RunWith(DeviceJUnit4ClassRunner.class)
34 public final class HdmiCecGeneralProtocolTest extends BaseHdmiCecCtsTest {
35 
36     @Rule
37     public RuleChain ruleChain =
38             RuleChain.outerRule(CecRules.requiresCec(this))
39                     .around(CecRules.requiresLeanback(this))
40                     .around(CecRules.requiresPhysicalDevice(this))
41                     .around(CecRules.requiresDeviceType(this, HdmiCecConstants.CEC_DEVICE_TYPE_TV))
42                     .around(hdmiCecClient);
43 
44     /**
45      * Test HF4-2-5 (CEC 2.0)
46      *
47      * <p>Tests that the device ignores any additional trailing parameters in an otherwise correct
48      * CEC message.
49      *
50      * <p>e.g. If {@code 4F:82:20:00:80:20:00:00:00 (<Active Source>)} is sent to the DUT, the DUT
51      * should ignore the last byte of the parameter and treat it as a {@code <Active Source>}
52      * message.
53      */
54     @Test
cect_hf_ignoreAdditionalParams()55     public void cect_hf_ignoreAdditionalParams() throws Exception {
56         setCec20();
57 
58         int clientPhysicalAddress = hdmiCecClient.getPhysicalAddress();
59         int playbackPhysicalAddress = 0x2000;
60         if (playbackPhysicalAddress == clientPhysicalAddress) {
61             playbackPhysicalAddress = 0x1000;
62         }
63 
64         String parameterPlaybackPhysicalAddress = CecMessage.formatParams(playbackPhysicalAddress,
65                 HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH);
66         String routingChange = CecMessage.formatParams(String.valueOf(CecOperand.ROUTING_CHANGE));
67 
68         hdmiCecClient.broadcastReportPhysicalAddress(
69                 LogicalAddress.RECORDER_1, clientPhysicalAddress);
70         hdmiCecClient.broadcastActiveSource(LogicalAddress.RECORDER_1, clientPhysicalAddress);
71         waitForCondition(() ->
72                         getDumpsysActiveSourceLogicalAddress().equals(LogicalAddress.RECORDER_1),
73                 "Device has not registered expected logical address as active source.");
74         hdmiCecClient.broadcastReportPhysicalAddress(LogicalAddress.PLAYBACK_1,
75                 playbackPhysicalAddress);
76         hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1, LogicalAddress.BROADCAST,
77                 CecOperand.ACTIVE_SOURCE, parameterPlaybackPhysicalAddress + routingChange);
78         waitForCondition(() ->
79                         getDumpsysActiveSourceLogicalAddress().equals(LogicalAddress.PLAYBACK_1),
80                 "Device has not registered expected logical address as active source.");
81     }
82 
83     /**
84      * <p>Tests that the device ignores any additional trailing parameters in an otherwise correct
85      * CEC message.
86      *
87      * <p>e.g. If {@code 4F:82:20:00:80:20:00:00:00 (<Active Source>)} is sent to the DUT, the DUT
88      * should ignore the bytes after the first physical address, the additional <Routing Change>
89      * operand and physical addresses, and treat it as a {@code <Active Source>} message.
90      *
91      * <p>This is not an HDMI Forum 2.0 CTS test.
92      */
93     @Test
cectIgnoreAdditionalParamsAsMessage()94     public void cectIgnoreAdditionalParamsAsMessage() throws Exception {
95         setCec20();
96 
97         int clientPhysicalAddress = hdmiCecClient.getPhysicalAddress();
98         int playbackPhysicalAddress = 0x2000;
99         if (playbackPhysicalAddress == clientPhysicalAddress) {
100             playbackPhysicalAddress = 0x1000;
101         }
102         String parameterClientPhysicalAddress = CecMessage.formatParams(clientPhysicalAddress,
103                 HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH);
104         String parameterPlaybackPhysicalAddress = CecMessage.formatParams(playbackPhysicalAddress,
105                 HdmiCecConstants.PHYSICAL_ADDRESS_LENGTH);
106         String routingChange = CecMessage.formatParams(String.valueOf(CecOperand.ROUTING_CHANGE));
107 
108         hdmiCecClient.broadcastReportPhysicalAddress(
109                 LogicalAddress.RECORDER_1, clientPhysicalAddress);
110         hdmiCecClient.broadcastActiveSource(LogicalAddress.RECORDER_1, clientPhysicalAddress);
111         waitForCondition(() ->
112                         getDumpsysActiveSourceLogicalAddress().equals(LogicalAddress.RECORDER_1),
113                 "Device has not registered expected logical address as active source.");
114         hdmiCecClient.broadcastReportPhysicalAddress(LogicalAddress.PLAYBACK_1,
115                 playbackPhysicalAddress);
116         hdmiCecClient.sendCecMessage(LogicalAddress.PLAYBACK_1, LogicalAddress.BROADCAST,
117                 CecOperand.ACTIVE_SOURCE, parameterPlaybackPhysicalAddress
118                         + routingChange + parameterPlaybackPhysicalAddress
119                         + parameterClientPhysicalAddress);
120         waitForCondition(() ->
121                         getDumpsysActiveSourceLogicalAddress().equals(LogicalAddress.PLAYBACK_1),
122                 "Device has not registered expected logical address as active source.");
123     }
124 }
125