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 package com.android.server.hdmi; 17 18 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; 19 import static com.android.server.hdmi.Constants.ABORT_UNRECOGNIZED_OPCODE; 20 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; 21 import static com.android.server.hdmi.Constants.ADDR_BROADCAST; 22 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1; 23 import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2; 24 import static com.android.server.hdmi.Constants.ADDR_RECORDER_1; 25 import static com.android.server.hdmi.Constants.ADDR_TV; 26 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC; 27 28 import static com.google.common.truth.Truth.assertThat; 29 30 import static org.junit.Assert.assertFalse; 31 import static org.junit.Assert.assertTrue; 32 import static org.mockito.ArgumentMatchers.any; 33 import static org.mockito.ArgumentMatchers.anyInt; 34 import static org.mockito.Mockito.eq; 35 import static org.mockito.Mockito.never; 36 import static org.mockito.Mockito.spy; 37 import static org.mockito.Mockito.times; 38 import static org.mockito.Mockito.verify; 39 40 import android.content.Context; 41 import android.hardware.hdmi.HdmiControlManager; 42 import android.hardware.hdmi.HdmiDeviceInfo; 43 import android.hardware.hdmi.HdmiPortInfo; 44 import android.hardware.hdmi.IHdmiControlCallback; 45 import android.hardware.tv.cec.V1_0.SendMessageResult; 46 import android.media.AudioManager; 47 import android.os.Looper; 48 import android.os.test.TestLooper; 49 import android.platform.test.annotations.Presubmit; 50 51 import androidx.test.InstrumentationRegistry; 52 import androidx.test.filters.SmallTest; 53 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.junit.runners.JUnit4; 58 59 import java.util.ArrayList; 60 import java.util.Collections; 61 import java.util.List; 62 import java.util.concurrent.TimeUnit; 63 64 @SmallTest 65 @Presubmit 66 @RunWith(JUnit4.class) 67 /** Tests for {@link HdmiCecLocalDeviceTv} class. */ 68 public class HdmiCecLocalDeviceTvTest { 69 private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1; 70 private static final int PORT_1 = 1; 71 72 private static final String[] SADS_NOT_TO_QUERY = new String[]{ 73 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MPEG1, 74 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_AAC, 75 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DTS, 76 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_ATRAC, 77 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO, 78 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DDP, 79 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DTSHD, 80 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_TRUEHD, 81 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_DST, 82 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, 83 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MAX}; 84 private static final HdmiCecMessage SAD_QUERY = 85 HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(ADDR_TV, ADDR_AUDIO_SYSTEM, 86 new int[]{Constants.AUDIO_CODEC_LPCM, Constants.AUDIO_CODEC_DD, 87 Constants.AUDIO_CODEC_MP3, Constants.AUDIO_CODEC_MPEG2}); 88 89 private HdmiControlService mHdmiControlService; 90 private HdmiCecController mHdmiCecController; 91 private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv; 92 private FakeNativeWrapper mNativeWrapper; 93 private HdmiEarcController mHdmiEarcController; 94 private FakeEarcNativeWrapper mEarcNativeWrapper; 95 private FakePowerManagerWrapper mPowerManager; 96 private Looper mMyLooper; 97 private TestLooper mTestLooper = new TestLooper(); 98 private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); 99 private int mTvPhysicalAddress; 100 private int mTvLogicalAddress; 101 private boolean mWokenUp; 102 private boolean mEarcBlocksArc; 103 private List<DeviceEventListener> mDeviceEventListeners = new ArrayList<>(); 104 105 private class DeviceEventListener { 106 private HdmiDeviceInfo mDevice; 107 private int mStatus; 108 DeviceEventListener(HdmiDeviceInfo device, int status)109 DeviceEventListener(HdmiDeviceInfo device, int status) { 110 this.mDevice = device; 111 this.mStatus = status; 112 } 113 getStatus()114 int getStatus() { 115 return mStatus; 116 } 117 getDeviceInfo()118 HdmiDeviceInfo getDeviceInfo() { 119 return mDevice; 120 } 121 } 122 123 private FakeAudioFramework mAudioFramework; 124 private AudioManagerWrapper mAudioManager; 125 126 @Before setUp()127 public void setUp() { 128 Context context = InstrumentationRegistry.getTargetContext(); 129 mMyLooper = mTestLooper.getLooper(); 130 131 mAudioFramework = new FakeAudioFramework(); 132 mAudioManager = spy(mAudioFramework.getAudioManager()); 133 134 mHdmiControlService = 135 new HdmiControlService(InstrumentationRegistry.getTargetContext(), 136 Collections.singletonList(HdmiDeviceInfo.DEVICE_TV), 137 mAudioManager, mAudioFramework.getAudioDeviceVolumeManager()) { 138 @Override 139 void wakeUp() { 140 mWokenUp = true; 141 super.wakeUp(); 142 } 143 @Override 144 boolean isCecControlEnabled() { 145 return true; 146 } 147 148 @Override 149 boolean isTvDevice() { 150 return true; 151 } 152 153 @Override 154 protected void writeStringSystemProperty(String key, String value) { 155 // do nothing 156 } 157 158 @Override 159 boolean isPowerStandby() { 160 return false; 161 } 162 163 @Override 164 boolean isPowerStandbyOrTransient() { 165 return false; 166 } 167 168 @Override 169 void invokeDeviceEventListeners(HdmiDeviceInfo device, int status) { 170 mDeviceEventListeners.add(new DeviceEventListener(device, status)); 171 } 172 173 @Override 174 protected boolean earcBlocksArcConnection() { 175 return mEarcBlocksArc; 176 } 177 }; 178 179 mHdmiControlService.setIoLooper(mMyLooper); 180 mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); 181 mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); 182 mNativeWrapper = new FakeNativeWrapper(); 183 mHdmiCecController = HdmiCecController.createWithNativeWrapper( 184 mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); 185 mHdmiControlService.setCecController(mHdmiCecController); 186 mEarcNativeWrapper = new FakeEarcNativeWrapper(); 187 mHdmiEarcController = HdmiEarcController.createWithNativeWrapper( 188 mHdmiControlService, mEarcNativeWrapper); 189 mHdmiControlService.setEarcController(mHdmiEarcController); 190 mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); 191 HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[2]; 192 hdmiPortInfos[0] = new HdmiPortInfo.Builder(1, HdmiPortInfo.PORT_INPUT, 0x1000) 193 .setCecSupported(true) 194 .setMhlSupported(false) 195 .setArcSupported(false) 196 .setEarcSupported(false) 197 .build(); 198 hdmiPortInfos[1] = 199 new HdmiPortInfo.Builder(2, HdmiPortInfo.PORT_INPUT, 0x2000) 200 .setCecSupported(true) 201 .setMhlSupported(false) 202 .setArcSupported(true) 203 .setEarcSupported(true) 204 .build(); 205 mNativeWrapper.setPortInfo(hdmiPortInfos); 206 mHdmiControlService.initService(); 207 mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); 208 mPowerManager = new FakePowerManagerWrapper(context); 209 mHdmiControlService.setPowerManager(mPowerManager); 210 mTvPhysicalAddress = 0x0000; 211 mEarcBlocksArc = false; 212 mNativeWrapper.setPhysicalAddress(mTvPhysicalAddress); 213 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_DISABLED); 214 mTestLooper.dispatchAll(); 215 mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); 216 mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(); 217 mLocalDevices.add(mHdmiCecLocalDeviceTv); 218 for (String sad : SADS_NOT_TO_QUERY) { 219 mHdmiControlService.getHdmiCecConfig().setIntValue( 220 sad, HdmiControlManager.QUERY_SAD_DISABLED); 221 } 222 mNativeWrapper.clearResultMessages(); 223 } 224 225 private static class TestCallback extends IHdmiControlCallback.Stub { 226 private final ArrayList<Integer> mCallbackResult = new ArrayList<Integer>(); 227 228 @Override onComplete(int result)229 public void onComplete(int result) { 230 mCallbackResult.add(result); 231 } 232 getResult()233 private int getResult() { 234 assertThat(mCallbackResult.size()).isEqualTo(1); 235 return mCallbackResult.get(0); 236 } 237 } 238 239 initiateArcAndValidate()240 private void initiateArcAndValidate() { 241 HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( 242 ADDR_AUDIO_SYSTEM, 243 ADDR_TV); 244 245 mNativeWrapper.onCecMessage(initiateArc); 246 mTestLooper.dispatchAll(); 247 248 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 249 ADDR_TV, 250 ADDR_AUDIO_SYSTEM); 251 // <Report ARC Initiated> should only be sent after SAD querying is done 252 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); 253 254 // Finish querying SADs 255 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 256 mNativeWrapper.clearResultMessages(); 257 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 258 mTestLooper.dispatchAll(); 259 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 260 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 261 mTestLooper.dispatchAll(); 262 263 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); 264 mNativeWrapper.clearResultMessages(); 265 } 266 initateSamAndValidate()267 private void initateSamAndValidate() { 268 // Record that previous system audio mode is on. 269 mHdmiCecLocalDeviceTv.setSystemAudioControlFeatureEnabled(true); 270 271 HdmiCecFeatureAction action = new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv, 272 ADDR_AUDIO_SYSTEM); 273 mHdmiCecLocalDeviceTv.addAndStartAction(action); 274 mTestLooper.dispatchAll(); 275 276 HdmiCecMessage giveSystemAudioModeStatus = 277 HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus( 278 mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(), 279 ADDR_AUDIO_SYSTEM); 280 281 assertThat(mNativeWrapper.getResultMessages()).contains(giveSystemAudioModeStatus); 282 283 HdmiCecMessage reportSystemAudioMode = 284 HdmiCecMessageBuilder.buildReportSystemAudioMode( 285 ADDR_AUDIO_SYSTEM, 286 mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(), 287 true); 288 mHdmiControlService.handleCecCommand(reportSystemAudioMode); 289 mTestLooper.dispatchAll(); 290 291 assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); 292 } 293 294 @Test initialPowerStateIsStandby()295 public void initialPowerStateIsStandby() { 296 assertThat(mHdmiCecLocalDeviceTv.getPowerStatus()).isEqualTo( 297 HdmiControlManager.POWER_STATUS_STANDBY); 298 } 299 300 @Test onAddressAllocated_invokesDeviceDiscovery()301 public void onAddressAllocated_invokesDeviceDiscovery() { 302 mHdmiControlService.getHdmiCecNetwork().clearLocalDevices(); 303 mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); 304 mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC); 305 306 mTestLooper.dispatchAll(); 307 308 // Check for for <Give Physical Address> being sent to available device (ADDR_PLAYBACK_1). 309 // This message is sent as part of the DeviceDiscoveryAction to available devices. 310 HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(ADDR_TV, 311 ADDR_PLAYBACK_1); 312 assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress); 313 } 314 315 @Test getActiveSource_noActiveSource()316 public void getActiveSource_noActiveSource() { 317 mHdmiControlService.setActiveSource(Constants.ADDR_UNREGISTERED, 318 Constants.INVALID_PHYSICAL_ADDRESS, "HdmiControlServiceTest"); 319 mHdmiCecLocalDeviceTv.setActivePath(HdmiDeviceInfo.PATH_INVALID); 320 321 assertThat(mHdmiControlService.getActiveSource()).isNull(); 322 } 323 324 @Test getActiveSource_deviceInNetworkIsActiveSource()325 public void getActiveSource_deviceInNetworkIsActiveSource() { 326 HdmiDeviceInfo externalDevice = HdmiDeviceInfo.cecDeviceBuilder() 327 .setLogicalAddress(Constants.ADDR_PLAYBACK_3) 328 .setPhysicalAddress(0x3000) 329 .setPortId(0) 330 .setDeviceType(Constants.ADDR_PLAYBACK_1) 331 .setVendorId(0) 332 .setDisplayName("Test Device") 333 .build(); 334 mHdmiControlService.getHdmiCecNetwork().addCecDevice(externalDevice); 335 mTestLooper.dispatchAll(); 336 337 mHdmiControlService.setActiveSource(externalDevice.getLogicalAddress(), 338 externalDevice.getPhysicalAddress(), "HdmiControlServiceTest"); 339 340 assertThat(mHdmiControlService.getActiveSource()).isEqualTo(externalDevice); 341 } 342 343 @Test getActiveSource_unknownLogicalAddressInNetworkIsActiveSource()344 public void getActiveSource_unknownLogicalAddressInNetworkIsActiveSource() { 345 HdmiDeviceInfo externalDevice = HdmiDeviceInfo.hardwarePort(0x1000, 1); 346 347 mHdmiControlService.setActiveSource(Constants.ADDR_UNREGISTERED, 348 externalDevice.getPhysicalAddress(), "HdmiControlServiceTest"); 349 mHdmiCecLocalDeviceTv.setActivePath(0x1000); 350 351 assertThat(mHdmiControlService.getActiveSource()).isEqualTo( 352 externalDevice); 353 } 354 355 @Test getActiveSource_unknownDeviceIsActiveSource()356 public void getActiveSource_unknownDeviceIsActiveSource() { 357 HdmiDeviceInfo externalDevice = HdmiDeviceInfo.cecDeviceBuilder() 358 .setLogicalAddress(Constants.ADDR_PLAYBACK_3) 359 .setPhysicalAddress(0x0000) 360 .setPortId(0) 361 .setDeviceType(ADDR_PLAYBACK_1) 362 .setVendorId(0) 363 .setDisplayName("Test Device") 364 .build(); 365 366 mHdmiControlService.setActiveSource(externalDevice.getLogicalAddress(), 367 externalDevice.getPhysicalAddress(), "HdmiControlServiceTest"); 368 mHdmiCecLocalDeviceTv.setActivePath(0x1000); 369 370 assertThat(mHdmiControlService.getActiveSource().getPhysicalAddress()).isEqualTo( 371 externalDevice.getPhysicalAddress()); 372 } 373 374 @Test shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv()375 public void shouldHandleTvPowerKey_CecEnabled_PowerControlModeTv() { 376 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 377 HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED, 378 HdmiControlManager.HDMI_CEC_CONTROL_ENABLED); 379 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setStringValue( 380 HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE, 381 HdmiControlManager.POWER_CONTROL_MODE_TV); 382 assertThat(mHdmiControlService.shouldHandleTvPowerKey()).isFalse(); 383 } 384 385 @Test tvWakeOnOneTouchPlay_TextViewOn_Enabled()386 public void tvWakeOnOneTouchPlay_TextViewOn_Enabled() { 387 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 388 HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 389 HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED); 390 mTestLooper.dispatchAll(); 391 mPowerManager.setInteractive(false); 392 HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1, 393 mTvLogicalAddress); 394 assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED); 395 mTestLooper.dispatchAll(); 396 assertThat(mPowerManager.isInteractive()).isTrue(); 397 } 398 399 @Test tvWakeOnOneTouchPlay_ImageViewOn_Enabled()400 public void tvWakeOnOneTouchPlay_ImageViewOn_Enabled() { 401 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 402 HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 403 HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED); 404 mTestLooper.dispatchAll(); 405 mPowerManager.setInteractive(false); 406 HdmiCecMessage imageViewOn = HdmiCecMessage.build(ADDR_PLAYBACK_1, mTvLogicalAddress, 407 Constants.MESSAGE_IMAGE_VIEW_ON, HdmiCecMessage.EMPTY_PARAM); 408 assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isEqualTo(Constants.HANDLED); 409 mTestLooper.dispatchAll(); 410 assertThat(mPowerManager.isInteractive()).isTrue(); 411 } 412 413 @Test tvWakeOnOneTouchPlay_TextViewOn_Disabled()414 public void tvWakeOnOneTouchPlay_TextViewOn_Disabled() { 415 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 416 HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 417 HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED); 418 mTestLooper.dispatchAll(); 419 mPowerManager.setInteractive(false); 420 HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1, 421 mTvLogicalAddress); 422 assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED); 423 mTestLooper.dispatchAll(); 424 assertThat(mPowerManager.isInteractive()).isFalse(); 425 } 426 427 @Test tvWakeOnOneTouchPlay_ImageViewOn_Disabled()428 public void tvWakeOnOneTouchPlay_ImageViewOn_Disabled() { 429 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 430 HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 431 HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED); 432 mTestLooper.dispatchAll(); 433 mPowerManager.setInteractive(false); 434 HdmiCecMessage imageViewOn = HdmiCecMessage.build(ADDR_PLAYBACK_1, mTvLogicalAddress, 435 Constants.MESSAGE_IMAGE_VIEW_ON, HdmiCecMessage.EMPTY_PARAM); 436 assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(imageViewOn)).isEqualTo(Constants.HANDLED); 437 mTestLooper.dispatchAll(); 438 assertThat(mPowerManager.isInteractive()).isFalse(); 439 } 440 441 @Test handleTextViewOn_Dreaming()442 public void handleTextViewOn_Dreaming() { 443 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 444 HdmiControlManager.CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 445 HdmiControlManager.TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED); 446 mTestLooper.dispatchAll(); 447 mPowerManager.setInteractive(true); 448 mWokenUp = false; 449 HdmiCecMessage textViewOn = HdmiCecMessageBuilder.buildTextViewOn(ADDR_PLAYBACK_1, 450 mTvLogicalAddress); 451 assertThat(mHdmiCecLocalDeviceTv.dispatchMessage(textViewOn)).isEqualTo(Constants.HANDLED); 452 mTestLooper.dispatchAll(); 453 assertThat(mPowerManager.isInteractive()).isTrue(); 454 assertThat(mWokenUp).isTrue(); 455 } 456 457 @Test tvSendStandbyOnSleep_Enabled()458 public void tvSendStandbyOnSleep_Enabled() { 459 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 460 HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP, 461 HdmiControlManager.TV_SEND_STANDBY_ON_SLEEP_ENABLED); 462 mTestLooper.dispatchAll(); 463 mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); 464 mTestLooper.dispatchAll(); 465 HdmiCecMessage standby = HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_BROADCAST); 466 assertThat(mNativeWrapper.getResultMessages()).contains(standby); 467 } 468 469 @Test tvSendStandbyOnSleep_Disabled()470 public void tvSendStandbyOnSleep_Disabled() { 471 mHdmiCecLocalDeviceTv.mService.getHdmiCecConfig().setIntValue( 472 HdmiControlManager.CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP, 473 HdmiControlManager.TV_SEND_STANDBY_ON_SLEEP_DISABLED); 474 mTestLooper.dispatchAll(); 475 mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); 476 mTestLooper.dispatchAll(); 477 HdmiCecMessage standby = HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_BROADCAST); 478 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(standby); 479 } 480 481 @Test getRcFeatures()482 public void getRcFeatures() { 483 ArrayList<Integer> features = new ArrayList<>(mHdmiCecLocalDeviceTv.getRcFeatures()); 484 assertThat(features.contains(Constants.RC_PROFILE_TV_NONE)).isTrue(); 485 assertThat(features.contains(Constants.RC_PROFILE_TV_ONE)).isFalse(); 486 assertThat(features.contains(Constants.RC_PROFILE_TV_TWO)).isFalse(); 487 assertThat(features.contains(Constants.RC_PROFILE_TV_THREE)).isFalse(); 488 assertThat(features.contains(Constants.RC_PROFILE_TV_FOUR)).isFalse(); 489 } 490 491 @Test startArcAction_enable_noAudioDevice()492 public void startArcAction_enable_noAudioDevice() { 493 mHdmiCecLocalDeviceTv.startArcAction(true); 494 495 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 496 ADDR_TV, 497 ADDR_AUDIO_SYSTEM); 498 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 499 ADDR_TV, 500 ADDR_AUDIO_SYSTEM); 501 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 502 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 503 } 504 505 506 @Test startArcAction_disable_noAudioDevice()507 public void startArcAction_disable_noAudioDevice() { 508 mHdmiCecLocalDeviceTv.startArcAction(false); 509 510 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 511 ADDR_TV, 512 ADDR_AUDIO_SYSTEM); 513 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 514 ADDR_TV, 515 ADDR_AUDIO_SYSTEM); 516 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 517 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 518 } 519 520 @Test startArcAction_enable_portDoesNotSupportArc()521 public void startArcAction_enable_portDoesNotSupportArc() { 522 // Emulate Audio device on port 0x1000 (does not support ARC) 523 mNativeWrapper.setPortConnectionStatus(1, true); 524 HdmiCecMessage reportPhysicalAddress = 525 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 526 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 527 mNativeWrapper.onCecMessage(reportPhysicalAddress); 528 529 mHdmiCecLocalDeviceTv.startArcAction(true); 530 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 531 ADDR_TV, 532 ADDR_AUDIO_SYSTEM); 533 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 534 ADDR_TV, 535 ADDR_AUDIO_SYSTEM); 536 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 537 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 538 } 539 540 @Test startArcAction_disable_portDoesNotSupportArc()541 public void startArcAction_disable_portDoesNotSupportArc() { 542 // Emulate Audio device on port 0x1000 (does not support ARC) 543 mNativeWrapper.setPortConnectionStatus(1, true); 544 HdmiCecMessage reportPhysicalAddress = 545 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 546 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 547 mNativeWrapper.onCecMessage(reportPhysicalAddress); 548 549 mHdmiCecLocalDeviceTv.startArcAction(false); 550 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 551 ADDR_TV, 552 ADDR_AUDIO_SYSTEM); 553 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 554 ADDR_TV, 555 ADDR_AUDIO_SYSTEM); 556 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 557 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 558 } 559 560 @Test startArcAction_enable_portSupportsArc()561 public void startArcAction_enable_portSupportsArc() { 562 // Emulate Audio device on port 0x2000 (supports ARC) 563 mNativeWrapper.setPortConnectionStatus(2, true); 564 HdmiCecMessage reportPhysicalAddress = 565 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 566 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 567 mNativeWrapper.onCecMessage(reportPhysicalAddress); 568 mTestLooper.dispatchAll(); 569 570 mHdmiCecLocalDeviceTv.startArcAction(true); 571 mTestLooper.dispatchAll(); 572 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 573 ADDR_TV, 574 ADDR_AUDIO_SYSTEM); 575 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 576 ADDR_TV, 577 ADDR_AUDIO_SYSTEM); 578 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 579 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 580 } 581 582 @Test startArcAction_disable_portSupportsArc()583 public void startArcAction_disable_portSupportsArc() { 584 // Emulate Audio device on port 0x2000 (supports ARC) 585 mNativeWrapper.setPortConnectionStatus(2, true); 586 HdmiCecMessage reportPhysicalAddress = 587 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 588 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 589 mNativeWrapper.onCecMessage(reportPhysicalAddress); 590 mTestLooper.dispatchAll(); 591 592 mHdmiCecLocalDeviceTv.startArcAction(false); 593 mTestLooper.dispatchAll(); 594 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 595 ADDR_TV, 596 ADDR_AUDIO_SYSTEM); 597 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 598 ADDR_TV, 599 ADDR_AUDIO_SYSTEM); 600 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 601 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 602 } 603 604 @Test handleInitiateArc_noAudioDevice()605 public void handleInitiateArc_noAudioDevice() { 606 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( 607 ADDR_AUDIO_SYSTEM, 608 ADDR_TV); 609 610 mNativeWrapper.onCecMessage(requestArcInitiation); 611 mTestLooper.dispatchAll(); 612 613 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 614 ADDR_TV, 615 ADDR_AUDIO_SYSTEM); 616 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); 617 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SAD_QUERY); 618 } 619 620 @Test handleInitiateArc_portDoesNotSupportArc()621 public void handleInitiateArc_portDoesNotSupportArc() { 622 // Emulate Audio device on port 0x1000 (does not support ARC) 623 mNativeWrapper.setPortConnectionStatus(1, true); 624 HdmiCecMessage reportPhysicalAddress = 625 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 626 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 627 mNativeWrapper.onCecMessage(reportPhysicalAddress); 628 629 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( 630 ADDR_AUDIO_SYSTEM, 631 ADDR_TV); 632 633 mNativeWrapper.onCecMessage(requestArcInitiation); 634 mTestLooper.dispatchAll(); 635 636 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 637 ADDR_TV, 638 ADDR_AUDIO_SYSTEM); 639 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); 640 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SAD_QUERY); 641 } 642 643 @Test handleInitiateArc_portSupportsArc()644 public void handleInitiateArc_portSupportsArc() { 645 // Emulate Audio device on port 0x2000 (supports ARC) 646 mNativeWrapper.setPortConnectionStatus(2, true); 647 HdmiCecMessage reportPhysicalAddress = 648 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 649 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 650 mNativeWrapper.onCecMessage(reportPhysicalAddress); 651 mTestLooper.dispatchAll(); 652 653 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( 654 ADDR_AUDIO_SYSTEM, 655 ADDR_TV); 656 657 mNativeWrapper.onCecMessage(requestArcInitiation); 658 mTestLooper.dispatchAll(); 659 660 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 661 ADDR_TV, 662 ADDR_AUDIO_SYSTEM); 663 // <Report ARC Initiated> should only be sent after SAD querying is done 664 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); 665 666 // Finish querying SADs 667 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 668 mNativeWrapper.clearResultMessages(); 669 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 670 mTestLooper.dispatchAll(); 671 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 672 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 673 mTestLooper.dispatchAll(); 674 675 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); 676 } 677 678 @Test handleTerminateArc_noAudioDevice()679 public void handleTerminateArc_noAudioDevice() { 680 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 681 ADDR_AUDIO_SYSTEM, 682 ADDR_TV); 683 684 mNativeWrapper.onCecMessage(terminateArc); 685 mTestLooper.dispatchAll(); 686 687 HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated( 688 ADDR_TV, 689 ADDR_AUDIO_SYSTEM); 690 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated); 691 } 692 693 @Test handleTerminateArc_portDoesNotSupportArc()694 public void handleTerminateArc_portDoesNotSupportArc() { 695 // Emulate Audio device on port 0x1000 (does not support ARC) 696 mNativeWrapper.setPortConnectionStatus(1, true); 697 HdmiCecMessage reportPhysicalAddress = 698 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 699 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 700 mNativeWrapper.onCecMessage(reportPhysicalAddress); 701 702 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 703 ADDR_AUDIO_SYSTEM, 704 ADDR_TV); 705 706 mNativeWrapper.onCecMessage(terminateArc); 707 mTestLooper.dispatchAll(); 708 709 HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated( 710 ADDR_TV, 711 ADDR_AUDIO_SYSTEM); 712 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated); 713 } 714 715 @Test handleTerminateArc_portSupportsArc()716 public void handleTerminateArc_portSupportsArc() { 717 // Emulate Audio device on port 0x2000 (supports ARC) 718 mNativeWrapper.setPortConnectionStatus(2, true); 719 HdmiCecMessage reportPhysicalAddress = 720 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 721 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 722 mNativeWrapper.onCecMessage(reportPhysicalAddress); 723 mTestLooper.dispatchAll(); 724 725 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 726 ADDR_AUDIO_SYSTEM, 727 ADDR_TV); 728 729 mNativeWrapper.onCecMessage(terminateArc); 730 mTestLooper.dispatchAll(); 731 732 HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated( 733 ADDR_TV, 734 ADDR_AUDIO_SYSTEM); 735 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated); 736 } 737 738 @Test supportsRecordTvScreen()739 public void supportsRecordTvScreen() { 740 HdmiCecMessage recordTvScreen = HdmiCecMessage.build(ADDR_RECORDER_1, mTvLogicalAddress, 741 Constants.MESSAGE_RECORD_TV_SCREEN, HdmiCecMessage.EMPTY_PARAM); 742 743 mNativeWrapper.onCecMessage(recordTvScreen); 744 mTestLooper.dispatchAll(); 745 746 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 747 mTvLogicalAddress, ADDR_RECORDER_1, Constants.MESSAGE_RECORD_TV_SCREEN, 748 ABORT_UNRECOGNIZED_OPCODE); 749 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort); 750 } 751 752 @Test handleReportAudioStatus_SamOnArcOff_setStreamVolumeNotCalled()753 public void handleReportAudioStatus_SamOnArcOff_setStreamVolumeNotCalled() { 754 mHdmiControlService.getHdmiCecConfig().setIntValue( 755 HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, 756 HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED); 757 // Emulate Audio device on port 0x1000 (does not support ARC) 758 mNativeWrapper.setPortConnectionStatus(1, true); 759 HdmiCecMessage reportPhysicalAddress = 760 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 761 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 762 mNativeWrapper.onCecMessage(reportPhysicalAddress); 763 mTestLooper.dispatchAll(); 764 765 HdmiCecFeatureAction systemAudioAutoInitiationAction = 766 new SystemAudioAutoInitiationAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM); 767 mHdmiCecLocalDeviceTv.addAndStartAction(systemAudioAutoInitiationAction); 768 HdmiCecMessage reportSystemAudioMode = 769 HdmiCecMessageBuilder.buildReportSystemAudioMode( 770 ADDR_AUDIO_SYSTEM, 771 mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(), 772 true); 773 mHdmiControlService.handleCecCommand(reportSystemAudioMode); 774 775 mTestLooper.dispatchAll(); 776 777 // SAM must be on; ARC must be off 778 assertTrue(mHdmiCecLocalDeviceTv.isSystemAudioActivated()); 779 assertFalse(mHdmiCecLocalDeviceTv.isArcEstablished()); 780 781 HdmiCecMessage reportAudioStatus = HdmiCecMessageBuilder.buildReportAudioStatus( 782 ADDR_AUDIO_SYSTEM, 783 ADDR_TV, 784 50, // Volume of incoming message does not affect HDMI-CEC logic 785 false); 786 mNativeWrapper.onCecMessage(reportAudioStatus); 787 788 mTestLooper.dispatchAll(); 789 790 verify(mAudioManager, never()).setStreamVolume(anyInt(), anyInt(), anyInt()); 791 } 792 793 /** 794 * Tests that receiving a message from a device does not prevent it from being discovered 795 * by HotplugDetectionAction. 796 */ 797 @Test hotplugDetectionAction_discoversDeviceAfterMessageReceived()798 public void hotplugDetectionAction_discoversDeviceAfterMessageReceived() { 799 // Playback 1 sends a message before ACKing a poll 800 mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.NACK); 801 HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource( 802 ADDR_PLAYBACK_1, ADDR_TV); 803 mNativeWrapper.onCecMessage(activeSource); 804 mTestLooper.dispatchAll(); 805 806 // Playback 1 begins ACKing polls, allowing detection by HotplugDetectionAction 807 mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS); 808 for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) { 809 mTestLooper.moveTimeForward( 810 TimeUnit.SECONDS.toMillis(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV)); 811 mTestLooper.dispatchAll(); 812 } 813 814 // Device sends <Give Physical Address> to Playback 1 after detecting it 815 HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress( 816 ADDR_TV, ADDR_PLAYBACK_1); 817 assertThat(mNativeWrapper.getResultMessages()).contains(givePhysicalAddress); 818 } 819 820 @Test hotplugDetectionActionClearsDevices()821 public void hotplugDetectionActionClearsDevices() { 822 mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); 823 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 824 .isEmpty(); 825 // Add a device to the network and assert that this device is included in the list of 826 // devices. 827 HdmiDeviceInfo infoPlayback = HdmiDeviceInfo.cecDeviceBuilder() 828 .setLogicalAddress(Constants.ADDR_PLAYBACK_2) 829 .setPhysicalAddress(0x1000) 830 .setPortId(PORT_1) 831 .setDeviceType(HdmiDeviceInfo.DEVICE_PLAYBACK) 832 .setVendorId(0x1000) 833 .setDisplayName("Playback 2") 834 .build(); 835 mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoPlayback); 836 mTestLooper.dispatchAll(); 837 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 838 .hasSize(1); 839 mDeviceEventListeners.clear(); 840 assertThat(mDeviceEventListeners.size()).isEqualTo(0); 841 842 // HAL detects a hotplug out. Assert that this device stays in the list of devices. 843 mHdmiControlService.onHotplug(PORT_1, false); 844 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 845 .hasSize(1); 846 assertThat(mDeviceEventListeners).isEmpty(); 847 mTestLooper.dispatchAll(); 848 // Make the device not acknowledge the poll message sent by the HotplugDetectionAction. 849 // Assert that this device is removed from the list of devices. 850 mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.NACK); 851 for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) { 852 mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV); 853 mTestLooper.dispatchAll(); 854 } 855 856 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 857 .isEmpty(); 858 assertThat(mDeviceEventListeners.size()).isEqualTo(1); 859 assertThat(mDeviceEventListeners.get(0).getStatus()) 860 .isEqualTo(HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); 861 HdmiDeviceInfo removedDeviceInfo = mDeviceEventListeners.get(0).getDeviceInfo(); 862 assertThat(removedDeviceInfo.getPortId()).isEqualTo(PORT_1); 863 assertThat(removedDeviceInfo.getLogicalAddress()).isEqualTo(Constants.ADDR_PLAYBACK_2); 864 assertThat(removedDeviceInfo.getPhysicalAddress()).isEqualTo(0x1000); 865 assertThat(removedDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_PLAYBACK); 866 } 867 868 @Test hotplugDetectionActionClearsDevices_AudioSystem()869 public void hotplugDetectionActionClearsDevices_AudioSystem() { 870 mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); 871 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 872 .isEmpty(); 873 // Add a device to the network and assert that this device is included in the list of 874 // devices. 875 HdmiDeviceInfo infoAudioSystem = HdmiDeviceInfo.cecDeviceBuilder() 876 .setLogicalAddress(ADDR_AUDIO_SYSTEM) 877 .setPhysicalAddress(0x1000) 878 .setPortId(PORT_1) 879 .setDeviceType(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) 880 .setVendorId(0x1000) 881 .setDisplayName("Audio System") 882 .build(); 883 mHdmiControlService.getHdmiCecNetwork().addCecDevice(infoAudioSystem); 884 mTestLooper.dispatchAll(); 885 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 886 .hasSize(1); 887 mDeviceEventListeners.clear(); 888 assertThat(mDeviceEventListeners.size()).isEqualTo(0); 889 890 // HAL detects a hotplug out. Assert that this device stays in the list of devices. 891 mHdmiControlService.onHotplug(PORT_1, false); 892 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 893 .hasSize(1); 894 assertThat(mDeviceEventListeners).isEmpty(); 895 mTestLooper.dispatchAll(); 896 // Make the device not acknowledge the poll message sent by the HotplugDetectionAction. 897 // Assert that this device is removed from the list of devices. 898 mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.NACK); 899 for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) { 900 mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV); 901 mTestLooper.dispatchAll(); 902 } 903 904 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 905 .isEmpty(); 906 assertThat(mDeviceEventListeners.size()).isEqualTo(1); 907 assertThat(mDeviceEventListeners.get(0).getStatus()) 908 .isEqualTo(HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE); 909 HdmiDeviceInfo removedDeviceInfo = mDeviceEventListeners.get(0).getDeviceInfo(); 910 assertThat(removedDeviceInfo.getPortId()).isEqualTo(PORT_1); 911 assertThat(removedDeviceInfo.getLogicalAddress()).isEqualTo(Constants.ADDR_AUDIO_SYSTEM); 912 assertThat(removedDeviceInfo.getPhysicalAddress()).isEqualTo(0x1000); 913 assertThat(removedDeviceInfo.getDeviceType()).isEqualTo(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 914 } 915 916 @Test listenerInvokedIfPhysicalAddressReported()917 public void listenerInvokedIfPhysicalAddressReported() { 918 mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); 919 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 920 .isEmpty(); 921 HdmiCecMessage reportPhysicalAddress = 922 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 923 ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK); 924 mNativeWrapper.onCecMessage(reportPhysicalAddress); 925 mTestLooper.dispatchAll(); 926 927 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 928 .hasSize(1); 929 assertThat(mDeviceEventListeners.size()).isEqualTo(1); 930 assertThat(mDeviceEventListeners.get(0).getStatus()) 931 .isEqualTo(HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); 932 } 933 934 @Test listenerNotInvokedIfPhysicalAddressUnknown()935 public void listenerNotInvokedIfPhysicalAddressUnknown() { 936 mHdmiControlService.getHdmiCecNetwork().clearDeviceList(); 937 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 938 .isEmpty(); 939 HdmiCecMessage setOsdName = HdmiCecMessageBuilder.buildSetOsdNameCommand( 940 ADDR_PLAYBACK_2, ADDR_TV, "Playback 2"); 941 mNativeWrapper.onCecMessage(setOsdName); 942 mTestLooper.dispatchAll(); 943 944 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 945 .hasSize(1); 946 assertThat(mDeviceEventListeners).isEmpty(); 947 948 // When the device reports its physical address, the listener eventually is invoked. 949 HdmiCecMessage reportPhysicalAddress = 950 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 951 ADDR_PLAYBACK_2, 0x1000, HdmiDeviceInfo.DEVICE_PLAYBACK); 952 mNativeWrapper.onCecMessage(reportPhysicalAddress); 953 mTestLooper.dispatchAll(); 954 955 assertThat(mHdmiControlService.getHdmiCecNetwork().getDeviceInfoList(false)) 956 .hasSize(1); 957 assertThat(mDeviceEventListeners.size()).isEqualTo(1); 958 assertThat(mDeviceEventListeners.get(0).getStatus()) 959 .isEqualTo(HdmiControlManager.DEVICE_EVENT_ADD_DEVICE); 960 } 961 962 @Test receiveSetAudioVolumeLevel_samNotActivated_noFeatureAbort_volumeChanges()963 public void receiveSetAudioVolumeLevel_samNotActivated_noFeatureAbort_volumeChanges() { 964 mAudioFramework.setStreamMaxVolume(AudioManager.STREAM_MUSIC, 25); 965 966 // Max volume of STREAM_MUSIC is retrieved on boot 967 mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); 968 mTestLooper.dispatchAll(); 969 970 mNativeWrapper.onCecMessage(SetAudioVolumeLevelMessage.build( 971 ADDR_PLAYBACK_1, 972 ADDR_TV, 973 20)); 974 mTestLooper.dispatchAll(); 975 976 // <Feature Abort>[Not in correct mode] not sent 977 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 978 ADDR_TV, 979 ADDR_PLAYBACK_1, 980 Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL, 981 Constants.ABORT_NOT_IN_CORRECT_MODE); 982 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(featureAbort); 983 984 // <Set Audio Volume Level> uses volume range [0, 100]; STREAM_MUSIC uses range [0, 25] 985 verify(mAudioManager).setStreamVolume(eq(AudioManager.STREAM_MUSIC), eq(5), anyInt()); 986 } 987 988 @Test receiveSetAudioVolumeLevel_samActivated_respondsFeatureAbort_noVolumeChange()989 public void receiveSetAudioVolumeLevel_samActivated_respondsFeatureAbort_noVolumeChange() { 990 mHdmiControlService.getHdmiCecConfig().setIntValue( 991 HdmiControlManager.CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, 992 HdmiControlManager.SYSTEM_AUDIO_CONTROL_ENABLED); 993 994 mNativeWrapper.onCecMessage(HdmiCecMessageBuilder.buildSetSystemAudioMode( 995 ADDR_AUDIO_SYSTEM, ADDR_TV, true)); 996 mTestLooper.dispatchAll(); 997 998 mNativeWrapper.onCecMessage(SetAudioVolumeLevelMessage.build( 999 ADDR_PLAYBACK_1, ADDR_TV, 50)); 1000 mTestLooper.dispatchAll(); 1001 1002 // <Feature Abort>[Not in correct mode] sent 1003 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 1004 ADDR_TV, 1005 ADDR_PLAYBACK_1, 1006 Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL, 1007 Constants.ABORT_NOT_IN_CORRECT_MODE); 1008 assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort); 1009 1010 // AudioManager not notified of volume change 1011 verify(mAudioManager, never()).setStreamVolume(eq(AudioManager.STREAM_MUSIC), anyInt(), 1012 anyInt()); 1013 } 1014 1015 @Test tvSendRequestArcTerminationOnSleep()1016 public void tvSendRequestArcTerminationOnSleep() { 1017 // Emulate Audio device on port 0x2000 (supports ARC) 1018 mNativeWrapper.setPortConnectionStatus(2, true); 1019 HdmiCecMessage reportPhysicalAddress = 1020 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1021 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1022 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1023 mTestLooper.dispatchAll(); 1024 1025 mHdmiCecLocalDeviceTv.startArcAction(true); 1026 mTestLooper.dispatchAll(); 1027 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1028 ADDR_TV, 1029 ADDR_AUDIO_SYSTEM); 1030 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1031 ADDR_TV, 1032 ADDR_AUDIO_SYSTEM); 1033 HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( 1034 ADDR_AUDIO_SYSTEM, 1035 ADDR_TV); 1036 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 1037 ADDR_TV, 1038 ADDR_AUDIO_SYSTEM); 1039 1040 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1041 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 1042 1043 mNativeWrapper.onCecMessage(initiateArc); 1044 mTestLooper.dispatchAll(); 1045 1046 // Finish querying SADs 1047 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 1048 mNativeWrapper.clearResultMessages(); 1049 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 1050 mTestLooper.dispatchAll(); 1051 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 1052 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 1053 mTestLooper.dispatchAll(); 1054 1055 // ARC should be established after RequestSadAction is finished 1056 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); 1057 1058 mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF); 1059 mTestLooper.dispatchAll(); 1060 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1061 } 1062 1063 @Test startArcAction_enable_earcBlocksArc()1064 public void startArcAction_enable_earcBlocksArc() { 1065 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1066 mTestLooper.dispatchAll(); 1067 1068 mEarcBlocksArc = true; 1069 1070 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1071 mNativeWrapper.setPortConnectionStatus(2, true); 1072 HdmiCecMessage reportPhysicalAddress = 1073 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1074 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1075 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1076 mTestLooper.dispatchAll(); 1077 1078 mHdmiCecLocalDeviceTv.startArcAction(true); 1079 mTestLooper.dispatchAll(); 1080 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1081 ADDR_TV, 1082 ADDR_AUDIO_SYSTEM); 1083 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1084 ADDR_TV, 1085 ADDR_AUDIO_SYSTEM); 1086 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 1087 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 1088 } 1089 1090 @Test startArcAction_enable_earcDoesNotBlockArc()1091 public void startArcAction_enable_earcDoesNotBlockArc() { 1092 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1093 mTestLooper.dispatchAll(); 1094 1095 mEarcBlocksArc = false; 1096 1097 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1098 mNativeWrapper.setPortConnectionStatus(2, true); 1099 HdmiCecMessage reportPhysicalAddress = 1100 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1101 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1102 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1103 mTestLooper.dispatchAll(); 1104 1105 mHdmiCecLocalDeviceTv.startArcAction(true); 1106 mTestLooper.dispatchAll(); 1107 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1108 ADDR_TV, 1109 ADDR_AUDIO_SYSTEM); 1110 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1111 ADDR_TV, 1112 ADDR_AUDIO_SYSTEM); 1113 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1114 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcTermination); 1115 } 1116 1117 @Test startArcAction_disable_earcBlocksArc()1118 public void startArcAction_disable_earcBlocksArc() { 1119 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1120 mTestLooper.dispatchAll(); 1121 1122 mEarcBlocksArc = true; 1123 1124 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1125 mNativeWrapper.setPortConnectionStatus(2, true); 1126 HdmiCecMessage reportPhysicalAddress = 1127 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1128 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1129 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1130 mTestLooper.dispatchAll(); 1131 1132 mHdmiCecLocalDeviceTv.startArcAction(false); 1133 mTestLooper.dispatchAll(); 1134 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1135 ADDR_TV, 1136 ADDR_AUDIO_SYSTEM); 1137 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1138 ADDR_TV, 1139 ADDR_AUDIO_SYSTEM); 1140 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(requestArcInitiation); 1141 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1142 } 1143 1144 @Test handleInitiateArc_earcBlocksArc()1145 public void handleInitiateArc_earcBlocksArc() { 1146 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1147 mTestLooper.dispatchAll(); 1148 1149 mEarcBlocksArc = true; 1150 1151 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1152 mNativeWrapper.setPortConnectionStatus(2, true); 1153 HdmiCecMessage reportPhysicalAddress = 1154 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1155 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1156 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1157 mTestLooper.dispatchAll(); 1158 1159 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( 1160 ADDR_AUDIO_SYSTEM, 1161 ADDR_TV); 1162 1163 mNativeWrapper.onCecMessage(requestArcInitiation); 1164 mTestLooper.dispatchAll(); 1165 1166 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 1167 ADDR_TV, 1168 ADDR_AUDIO_SYSTEM, 1169 Constants.MESSAGE_INITIATE_ARC, 1170 Constants.ABORT_NOT_IN_CORRECT_MODE); 1171 assertThat(mNativeWrapper.getResultMessages()).contains(featureAbort); 1172 } 1173 1174 @Test handleInitiateArc_earcDoesNotBlockArc()1175 public void handleInitiateArc_earcDoesNotBlockArc() { 1176 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1177 mTestLooper.dispatchAll(); 1178 1179 mEarcBlocksArc = false; 1180 1181 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1182 mNativeWrapper.setPortConnectionStatus(2, true); 1183 HdmiCecMessage reportPhysicalAddress = 1184 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1185 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1186 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1187 mTestLooper.dispatchAll(); 1188 1189 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildInitiateArc( 1190 ADDR_AUDIO_SYSTEM, 1191 ADDR_TV); 1192 1193 mNativeWrapper.onCecMessage(requestArcInitiation); 1194 mTestLooper.dispatchAll(); 1195 1196 HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated( 1197 ADDR_TV, 1198 ADDR_AUDIO_SYSTEM); 1199 // <Report ARC Initiated> should only be sent after SAD querying is done 1200 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated); 1201 1202 // Finish querying SADs 1203 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 1204 mNativeWrapper.clearResultMessages(); 1205 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 1206 mTestLooper.dispatchAll(); 1207 assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY); 1208 mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS); 1209 mTestLooper.dispatchAll(); 1210 1211 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated); 1212 } 1213 1214 @Test handleTerminateArc_earcBlocksArc()1215 public void handleTerminateArc_earcBlocksArc() { 1216 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1217 mTestLooper.dispatchAll(); 1218 1219 mEarcBlocksArc = true; 1220 1221 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1222 mNativeWrapper.setPortConnectionStatus(2, true); 1223 HdmiCecMessage reportPhysicalAddress = 1224 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1225 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1226 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1227 mTestLooper.dispatchAll(); 1228 1229 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 1230 ADDR_AUDIO_SYSTEM, 1231 ADDR_TV); 1232 1233 mNativeWrapper.onCecMessage(terminateArc); 1234 mTestLooper.dispatchAll(); 1235 1236 HdmiCecMessage reportArcTerminated = HdmiCecMessageBuilder.buildReportArcTerminated( 1237 ADDR_TV, 1238 ADDR_AUDIO_SYSTEM); 1239 assertThat(mNativeWrapper.getResultMessages()).contains(reportArcTerminated); 1240 } 1241 1242 @Test startArcAction_initiation_noAvr()1243 public void startArcAction_initiation_noAvr() { 1244 TestCallback callback = new TestCallback(); 1245 1246 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1247 mTestLooper.dispatchAll(); 1248 1249 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1250 } 1251 1252 @Test startArcAction_initiation_portNotConnected()1253 public void startArcAction_initiation_portNotConnected() { 1254 // Emulate Audio device on port 0x2000 (supports ARC) 1255 HdmiCecMessage reportPhysicalAddress = 1256 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1257 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1258 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1259 mTestLooper.dispatchAll(); 1260 // Emulate port disconnect 1261 mNativeWrapper.setPortConnectionStatus(2, false); 1262 1263 TestCallback callback = new TestCallback(); 1264 1265 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1266 mTestLooper.dispatchAll(); 1267 1268 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE); 1269 } 1270 1271 @Test startArcAction_initiation_portDoesNotSupportArc()1272 public void startArcAction_initiation_portDoesNotSupportArc() { 1273 // Emulate Audio device on port 0x1000 (Doesn´t support ARC) 1274 mNativeWrapper.setPortConnectionStatus(1, true); 1275 HdmiCecMessage reportPhysicalAddress = 1276 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1277 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1278 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1279 mTestLooper.dispatchAll(); 1280 1281 TestCallback callback = new TestCallback(); 1282 1283 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1284 mTestLooper.dispatchAll(); 1285 1286 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE); 1287 } 1288 1289 @Test startArcAction_initiation_indirectPhysicalAddress()1290 public void startArcAction_initiation_indirectPhysicalAddress() { 1291 // Emulate Audio device on port 0x2000 (Supports ARC) 1292 mNativeWrapper.setPortConnectionStatus(2, true); 1293 HdmiCecMessage reportPhysicalAddress = 1294 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1295 ADDR_AUDIO_SYSTEM, 0x2320, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1296 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1297 mTestLooper.dispatchAll(); 1298 1299 TestCallback callback = new TestCallback(); 1300 1301 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1302 mTestLooper.dispatchAll(); 1303 1304 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE); 1305 } 1306 1307 @Test startArcAction_initiation_earcBlocksArc()1308 public void startArcAction_initiation_earcBlocksArc() { 1309 // Emulate Audio device on port 0x2000 (Supports ARC) 1310 mNativeWrapper.setPortConnectionStatus(2, true); 1311 HdmiCecMessage reportPhysicalAddress = 1312 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1313 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1314 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1315 mTestLooper.dispatchAll(); 1316 1317 mEarcBlocksArc = true; 1318 1319 TestCallback callback = new TestCallback(); 1320 1321 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1322 mTestLooper.dispatchAll(); 1323 1324 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE); 1325 } 1326 1327 @Test startArcAction_initiation_messageNotAcked()1328 public void startArcAction_initiation_messageNotAcked() { 1329 // Emulate Audio device on port 0x2000 (Supports ARC) 1330 mNativeWrapper.setPortConnectionStatus(2, true); 1331 HdmiCecMessage reportPhysicalAddress = 1332 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1333 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1334 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1335 mTestLooper.dispatchAll(); 1336 1337 mNativeWrapper.setMessageSendResult( 1338 Constants.MESSAGE_REQUEST_ARC_INITIATION, SendMessageResult.NACK); 1339 mTestLooper.dispatchAll(); 1340 1341 TestCallback callback = new TestCallback(); 1342 1343 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1344 mTestLooper.dispatchAll(); 1345 1346 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1347 ADDR_TV, 1348 ADDR_AUDIO_SYSTEM); 1349 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1350 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1351 } 1352 1353 @Test startArcAction_initiation_timeout()1354 public void startArcAction_initiation_timeout() { 1355 // Emulate Audio device on port 0x2000 (Supports ARC) 1356 mNativeWrapper.setPortConnectionStatus(2, true); 1357 HdmiCecMessage reportPhysicalAddress = 1358 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1359 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1360 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1361 mTestLooper.dispatchAll(); 1362 1363 TestCallback callback = new TestCallback(); 1364 1365 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1366 mTestLooper.dispatchAll(); 1367 1368 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1369 ADDR_TV, 1370 ADDR_AUDIO_SYSTEM); 1371 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1372 mTestLooper.moveTimeForward(TIMEOUT_MS); 1373 mTestLooper.dispatchAll(); 1374 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT); 1375 } 1376 1377 @Test startArcAction_initiation_featureAbort()1378 public void startArcAction_initiation_featureAbort() { 1379 // Emulate Audio device on port 0x2000 (Supports ARC) 1380 mNativeWrapper.setPortConnectionStatus(2, true); 1381 HdmiCecMessage reportPhysicalAddress = 1382 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1383 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1384 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1385 mTestLooper.dispatchAll(); 1386 1387 TestCallback callback = new TestCallback(); 1388 1389 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1390 mTestLooper.dispatchAll(); 1391 1392 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1393 ADDR_TV, 1394 ADDR_AUDIO_SYSTEM); 1395 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1396 1397 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 1398 ADDR_AUDIO_SYSTEM, 1399 ADDR_TV, 1400 Constants.MESSAGE_REQUEST_ARC_INITIATION, 1401 Constants.ABORT_NOT_IN_CORRECT_MODE); 1402 mNativeWrapper.onCecMessage(featureAbort); 1403 mTestLooper.dispatchAll(); 1404 1405 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1406 } 1407 1408 @Test startArcAction_initiation_success()1409 public void startArcAction_initiation_success() { 1410 // Emulate Audio device on port 0x2000 (Supports ARC) 1411 mNativeWrapper.setPortConnectionStatus(2, true); 1412 HdmiCecMessage reportPhysicalAddress = 1413 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1414 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1415 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1416 mTestLooper.dispatchAll(); 1417 1418 TestCallback callback = new TestCallback(); 1419 1420 mHdmiCecLocalDeviceTv.startArcAction(true, callback); 1421 mTestLooper.dispatchAll(); 1422 1423 HdmiCecMessage requestArcInitiation = HdmiCecMessageBuilder.buildRequestArcInitiation( 1424 ADDR_TV, 1425 ADDR_AUDIO_SYSTEM); 1426 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcInitiation); 1427 1428 HdmiCecMessage initiateArc = HdmiCecMessageBuilder.buildInitiateArc( 1429 ADDR_AUDIO_SYSTEM, 1430 ADDR_TV); 1431 mNativeWrapper.onCecMessage(initiateArc); 1432 mTestLooper.dispatchAll(); 1433 1434 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); 1435 } 1436 1437 @Test startArcAction_termination_noAvr()1438 public void startArcAction_termination_noAvr() { 1439 TestCallback callback = new TestCallback(); 1440 1441 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1442 mTestLooper.dispatchAll(); 1443 1444 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1445 } 1446 1447 @Test startArcAction_termination_portDoesNotSupportArc()1448 public void startArcAction_termination_portDoesNotSupportArc() { 1449 // Emulate Audio device on port 0x1000 (Doesn´t support ARC) 1450 mNativeWrapper.setPortConnectionStatus(1, true); 1451 HdmiCecMessage reportPhysicalAddress = 1452 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1453 ADDR_AUDIO_SYSTEM, 0x1000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1454 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1455 mTestLooper.dispatchAll(); 1456 1457 TestCallback callback = new TestCallback(); 1458 1459 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1460 mTestLooper.dispatchAll(); 1461 1462 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_INCORRECT_MODE); 1463 } 1464 1465 @Test startArcAction_termination_messageNotAcked()1466 public void startArcAction_termination_messageNotAcked() { 1467 // Emulate Audio device on port 0x2000 (Supports ARC) 1468 mNativeWrapper.setPortConnectionStatus(2, true); 1469 HdmiCecMessage reportPhysicalAddress = 1470 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1471 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1472 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1473 mTestLooper.dispatchAll(); 1474 1475 mNativeWrapper.setMessageSendResult( 1476 Constants.MESSAGE_REQUEST_ARC_TERMINATION, SendMessageResult.NACK); 1477 mTestLooper.dispatchAll(); 1478 1479 TestCallback callback = new TestCallback(); 1480 1481 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1482 mTestLooper.dispatchAll(); 1483 1484 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1485 ADDR_TV, 1486 ADDR_AUDIO_SYSTEM); 1487 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1488 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1489 } 1490 1491 @Test startArcAction_termination_timeout()1492 public void startArcAction_termination_timeout() { 1493 // Emulate Audio device on port 0x2000 (Supports ARC) 1494 mNativeWrapper.setPortConnectionStatus(2, true); 1495 HdmiCecMessage reportPhysicalAddress = 1496 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1497 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1498 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1499 mTestLooper.dispatchAll(); 1500 1501 TestCallback callback = new TestCallback(); 1502 1503 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1504 mTestLooper.dispatchAll(); 1505 1506 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1507 ADDR_TV, 1508 ADDR_AUDIO_SYSTEM); 1509 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1510 mTestLooper.moveTimeForward(TIMEOUT_MS); 1511 mTestLooper.dispatchAll(); 1512 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TIMEOUT); 1513 } 1514 1515 @Test startArcAction_termination_featureAbort()1516 public void startArcAction_termination_featureAbort() { 1517 // Emulate Audio device on port 0x2000 (Supports ARC) 1518 mNativeWrapper.setPortConnectionStatus(2, true); 1519 HdmiCecMessage reportPhysicalAddress = 1520 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1521 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1522 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1523 mTestLooper.dispatchAll(); 1524 1525 TestCallback callback = new TestCallback(); 1526 1527 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1528 mTestLooper.dispatchAll(); 1529 1530 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1531 ADDR_TV, 1532 ADDR_AUDIO_SYSTEM); 1533 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1534 1535 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 1536 ADDR_AUDIO_SYSTEM, 1537 ADDR_TV, 1538 Constants.MESSAGE_REQUEST_ARC_TERMINATION, 1539 Constants.ABORT_NOT_IN_CORRECT_MODE); 1540 mNativeWrapper.onCecMessage(featureAbort); 1541 mTestLooper.dispatchAll(); 1542 1543 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE); 1544 } 1545 1546 @Test startArcAction_termination_success()1547 public void startArcAction_termination_success() { 1548 // Emulate Audio device on port 0x2000 (Supports ARC) 1549 mNativeWrapper.setPortConnectionStatus(2, true); 1550 HdmiCecMessage reportPhysicalAddress = 1551 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1552 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1553 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1554 mTestLooper.dispatchAll(); 1555 1556 TestCallback callback = new TestCallback(); 1557 1558 mHdmiCecLocalDeviceTv.startArcAction(false, callback); 1559 mTestLooper.dispatchAll(); 1560 1561 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1562 ADDR_TV, 1563 ADDR_AUDIO_SYSTEM); 1564 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1565 1566 HdmiCecMessage terminateArc = HdmiCecMessageBuilder.buildTerminateArc( 1567 ADDR_AUDIO_SYSTEM, 1568 ADDR_TV); 1569 mNativeWrapper.onCecMessage(terminateArc); 1570 mTestLooper.dispatchAll(); 1571 1572 assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS); 1573 } 1574 1575 @Test enableEarc_terminateArc()1576 public void enableEarc_terminateArc() { 1577 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1578 mNativeWrapper.setPortConnectionStatus(2, true); 1579 HdmiCecMessage reportPhysicalAddress = 1580 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1581 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1582 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1583 mTestLooper.dispatchAll(); 1584 1585 initiateArcAndValidate(); 1586 1587 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1588 mTestLooper.dispatchAll(); 1589 1590 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1591 ADDR_TV, 1592 ADDR_AUDIO_SYSTEM); 1593 1594 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1595 } 1596 1597 @Test fromArcToEarc_SamRemainsOn()1598 public void fromArcToEarc_SamRemainsOn() { 1599 initateSamAndValidate(); 1600 1601 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1602 mNativeWrapper.setPortConnectionStatus(2, true); 1603 HdmiCecMessage reportPhysicalAddress = 1604 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1605 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1606 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1607 mTestLooper.dispatchAll(); 1608 1609 initiateArcAndValidate(); 1610 1611 assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); 1612 1613 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1614 mTestLooper.dispatchAll(); 1615 1616 HdmiCecMessage requestArcTermination = HdmiCecMessageBuilder.buildRequestArcTermination( 1617 ADDR_TV, 1618 ADDR_AUDIO_SYSTEM); 1619 1620 assertThat(mNativeWrapper.getResultMessages()).contains(requestArcTermination); 1621 assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); 1622 } 1623 1624 @Test disableEarc_SamRemainsOn()1625 public void disableEarc_SamRemainsOn() { 1626 initateSamAndValidate(); 1627 1628 // Emulate Audio device on port 0x2000 (supports ARC and eARC) 1629 mNativeWrapper.setPortConnectionStatus(2, true); 1630 HdmiCecMessage reportPhysicalAddress = 1631 HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( 1632 ADDR_AUDIO_SYSTEM, 0x2000, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1633 mNativeWrapper.onCecMessage(reportPhysicalAddress); 1634 mTestLooper.dispatchAll(); 1635 1636 mHdmiControlService.setEarcEnabled(HdmiControlManager.EARC_FEATURE_ENABLED); 1637 mTestLooper.dispatchAll(); 1638 assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); 1639 1640 mHdmiControlService.initializeEarcLocalDevice(HdmiControlService.INITIATED_BY_BOOT_UP); 1641 HdmiEarcLocalDevice mHdmiEarcLocalDeviceTx = mHdmiControlService.getEarcLocalDevice(); 1642 mHdmiEarcLocalDeviceTx.handleEarcStateChange(Constants.HDMI_EARC_STATUS_EARC_CONNECTED); 1643 mTestLooper.moveTimeForward(HdmiEarcLocalDeviceTx.REPORT_CAPS_MAX_DELAY_MS + 1); 1644 mTestLooper.dispatchAll(); 1645 verify(mAudioManager, times(1)).setWiredDeviceConnectionState( 1646 any(), eq(1)); 1647 1648 assertThat(mHdmiControlService.isSystemAudioActivated()).isTrue(); 1649 1650 } 1651 } 1652