1 /* 2 * Copyright (C) 2020 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 static com.google.common.truth.Truth.assertWithMessage; 20 21 import android.hdmicec.cts.BaseHdmiCecCtsTest; 22 import android.hdmicec.cts.CecMessage; 23 import android.hdmicec.cts.CecOperand; 24 import android.hdmicec.cts.HdmiCecConstants; 25 import android.hdmicec.cts.HdmiControlManagerUtility; 26 import android.hdmicec.cts.LogicalAddress; 27 import android.hdmicec.cts.error.CecClientWrapperException; 28 import android.hdmicec.cts.error.ErrorCodes; 29 30 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 31 32 import org.junit.Before; 33 import org.junit.Rule; 34 import org.junit.Test; 35 import org.junit.rules.RuleChain; 36 import org.junit.runner.RunWith; 37 38 import java.util.concurrent.TimeUnit; 39 40 /** HDMI CEC Routing control tests (Section 11.1.2) */ 41 @RunWith(DeviceJUnit4ClassRunner.class) 42 public final class HdmiCecRoutingControlTest extends BaseHdmiCecCtsTest { 43 44 private static final int WAIT_TIME_MS = 1000; 45 46 @Rule 47 public RuleChain ruleChain = 48 RuleChain.outerRule(CecRules.requiresCec(this)) 49 .around(CecRules.requiresLeanback(this)) 50 .around(CecRules.requiresPhysicalDevice(this)) 51 .around(CecRules.requiresDeviceType(this, HdmiCecConstants.CEC_DEVICE_TYPE_TV)) 52 .around(hdmiCecClient); 53 HdmiCecRoutingControlTest()54 public HdmiCecRoutingControlTest() { 55 super(HdmiCecConstants.CEC_DEVICE_TYPE_TV, "-t", "r", "-t", "t", "-t", "p"); 56 } 57 58 @Before checkForInitialActiveSourceMessage()59 public void checkForInitialActiveSourceMessage() throws CecClientWrapperException { 60 try { 61 /* 62 * Check for the broadcasted <ACTIVE_SOURCE> message from Recorder_1, which was sent as 63 * a response to <SET_STREAM_PATH> message from the TV. 64 */ 65 String message = 66 hdmiCecClient.checkExpectedMessageFromClient( 67 LogicalAddress.RECORDER_1, CecOperand.ACTIVE_SOURCE); 68 } catch (CecClientWrapperException e) { 69 if (e.getErrorCode() != ErrorCodes.CecMessageNotFound) { 70 throw e; 71 } else { 72 /* 73 * In case the TV does not send <Set Stream Path> to CEC adapter, or the client does 74 * not make recorder active source, broadcast an <Active Source> message from the 75 * adapter. 76 */ 77 hdmiCecClient.broadcastActiveSource( 78 hdmiCecClient.getSelfDevice(), hdmiCecClient.getPhysicalAddress()); 79 try { 80 TimeUnit.MILLISECONDS.sleep(WAIT_TIME_MS); 81 } catch (InterruptedException ex) { 82 // Do nothing 83 } 84 } 85 } 86 } 87 88 /** 89 * Test 11.1.2-1 90 * 91 * <p>Tests that the device sends a {@code <Set Stream Path>} message if the user selects 92 * another source device. 93 */ 94 @Test cect_11_1_2_1_DutSendsSetStreamPathMessage()95 public void cect_11_1_2_1_DutSendsSetStreamPathMessage() throws Exception { 96 // Broadcast a <Report Physical Address> [2.1.0.0] message from Logical Address 3. 97 hdmiCecClient.broadcastReportPhysicalAddress(LogicalAddress.TUNER_1, 0x2100); 98 // Broadcast a <Report Physical Address> [2.2.0.0] message from Logical Address 4. 99 hdmiCecClient.broadcastReportPhysicalAddress(LogicalAddress.PLAYBACK_1, 0x2200); 100 TimeUnit.SECONDS.sleep(2); 101 // Make the device with LA 4 as the active source. 102 HdmiControlManagerUtility.selectDevice( 103 this, getDevice(), LogicalAddress.PLAYBACK_1.toString()); 104 String message = hdmiCecClient.checkExpectedOutput(CecOperand.SET_STREAM_PATH); 105 assertWithMessage("Device has not sent a Set Stream Path message to the selected device") 106 .that(CecMessage.getParams(message)) 107 .isEqualTo(0x2200); 108 } 109 110 /** 111 * Test 11.1.2-2 112 * 113 * <p>Tests that the device doesn't respond to a {@code <Request Active Source>} message when it 114 * is not the current active source. 115 */ 116 @Test cect_11_1_2_2_DutDoesNotRespondToRequestActiveSourceMessage()117 public void cect_11_1_2_2_DutDoesNotRespondToRequestActiveSourceMessage() throws Exception { 118 // Ensure that DUT is the active source. 119 HdmiControlManagerUtility.selectDevice(this, getDevice(), LogicalAddress.TV.toString()); 120 hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE); 121 // Broadcast an active source from the client device. 122 hdmiCecClient.broadcastActiveSource(hdmiCecClient.getSelfDevice()); 123 hdmiCecClient.sendCecMessage( 124 hdmiCecClient.getSelfDevice(), 125 LogicalAddress.BROADCAST, 126 CecOperand.REQUEST_ACTIVE_SOURCE); 127 hdmiCecClient.checkOutputDoesNotContainMessage( 128 LogicalAddress.BROADCAST, CecOperand.ACTIVE_SOURCE); 129 } 130 131 /** 132 * Test 11.1.2-3 133 * 134 * <p>Tests that the device responds correctly to a {@code <Request Active Source>} message when 135 * it is the current active source. 136 */ 137 @Test cect_11_1_2_3_DutDoesRespondToRequestActiveSourceMessage()138 public void cect_11_1_2_3_DutDoesRespondToRequestActiveSourceMessage() throws Exception { 139 // Make the TV device the active source. 140 HdmiControlManagerUtility.selectDevice(this, getDevice(), LogicalAddress.TV.toString()); 141 hdmiCecClient.sendCecMessage( 142 hdmiCecClient.getSelfDevice(), 143 LogicalAddress.BROADCAST, 144 CecOperand.REQUEST_ACTIVE_SOURCE); 145 hdmiCecClient.checkExpectedOutput(CecOperand.ACTIVE_SOURCE); 146 } 147 148 /** 149 * Test 11.1.2-4 150 * 151 * <p>Tests that the device accepts {@code <Inactive Source>} message. 152 */ 153 @Test cect_11_1_2_4_DutAcceptsInactiveSourceMessage()154 public void cect_11_1_2_4_DutAcceptsInactiveSourceMessage() throws Exception { 155 hdmiCecClient.sendCecMessage( 156 hdmiCecClient.getSelfDevice(), 157 LogicalAddress.TV, 158 CecOperand.INACTIVE_SOURCE, 159 CecMessage.formatParams(hdmiCecClient.getPhysicalAddress())); 160 hdmiCecClient.checkOutputDoesNotContainMessage( 161 hdmiCecClient.getSelfDevice(), 162 CecOperand.FEATURE_ABORT, 163 CecMessage.formatParams(CecOperand.INACTIVE_SOURCE.toString())); 164 } 165 } 166