1 /* 2 * Copyright (C) 2021 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 com.android.server.hdmi; 18 19 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; 20 import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import android.content.Context; 25 import android.hardware.hdmi.HdmiControlManager; 26 import android.hardware.hdmi.HdmiDeviceInfo; 27 import android.os.Looper; 28 import android.os.test.TestLooper; 29 import android.platform.test.annotations.Presubmit; 30 31 import androidx.test.InstrumentationRegistry; 32 import androidx.test.filters.SmallTest; 33 34 import com.android.server.hdmi.RequestSadAction.RequestSadCallback; 35 36 import org.junit.Before; 37 import org.junit.Test; 38 import org.junit.runner.RunWith; 39 import org.junit.runners.JUnit4; 40 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.Collections; 44 import java.util.List; 45 46 @SmallTest 47 @Presubmit 48 @RunWith(JUnit4.class) 49 public class RequestSadActionTest { 50 51 private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1; 52 private static final ArrayList<Integer> CODECS_TO_QUERY_1 = new ArrayList<Integer>( 53 Arrays.asList(Constants.AUDIO_CODEC_LPCM, Constants.AUDIO_CODEC_DD, 54 Constants.AUDIO_CODEC_MPEG1, Constants.AUDIO_CODEC_MP3)); 55 private static final ArrayList<Integer> CODECS_TO_QUERY_2 = new ArrayList<Integer>( 56 Arrays.asList(Constants.AUDIO_CODEC_MPEG2, Constants.AUDIO_CODEC_AAC, 57 Constants.AUDIO_CODEC_DTS, Constants.AUDIO_CODEC_ATRAC)); 58 private static final ArrayList<Integer> CODECS_TO_QUERY_3 = new ArrayList<Integer>( 59 Arrays.asList(Constants.AUDIO_CODEC_ONEBITAUDIO, Constants.AUDIO_CODEC_DDP, 60 Constants.AUDIO_CODEC_DTSHD, Constants.AUDIO_CODEC_TRUEHD)); 61 private static final ArrayList<Integer> CODECS_TO_QUERY_4 = new ArrayList<Integer>( 62 Arrays.asList(Constants.AUDIO_CODEC_DST, Constants.AUDIO_CODEC_WMAPRO, 63 Constants.AUDIO_CODEC_MAX)); 64 65 private HdmiControlService mHdmiControlService; 66 private HdmiCecController mHdmiCecController; 67 private HdmiCecLocalDeviceTv mHdmiCecLocalDeviceTv; 68 private FakeNativeWrapper mNativeWrapper; 69 private FakePowerManagerWrapper mPowerManager; 70 private Looper mMyLooper; 71 private TestLooper mTestLooper = new TestLooper(); 72 private int mTvLogicalAddress; 73 private List<byte[]> mSupportedSads; 74 private RequestSadCallback mCallback = 75 new RequestSadCallback() { 76 @Override 77 public void onRequestSadDone( 78 List<byte[]> supportedSads) { 79 mSupportedSads = supportedSads; 80 } 81 }; 82 concatenateSads(List<byte[]> sads)83 private static byte[] concatenateSads(List<byte[]> sads) { 84 byte[] concatenatedSads = new byte[sads.size() * 3]; 85 for (int i = 0; i < sads.size(); i++) { 86 for (int j = 0; j < 3; j++) { 87 concatenatedSads[3 * i + j] = sads.get(i)[j]; 88 } 89 } 90 return concatenatedSads; 91 } 92 93 @Before setUp()94 public void setUp() { 95 Context context = InstrumentationRegistry.getTargetContext(); 96 mMyLooper = mTestLooper.getLooper(); 97 98 FakeAudioFramework audioFramework = new FakeAudioFramework(); 99 100 mHdmiControlService = 101 new HdmiControlService(context, Collections.singletonList(HdmiDeviceInfo.DEVICE_TV), 102 audioFramework.getAudioManager(), 103 audioFramework.getAudioDeviceVolumeManager()) { 104 @Override 105 boolean isCecControlEnabled() { 106 return true; 107 } 108 109 @Override 110 protected void writeStringSystemProperty(String key, String value) { 111 // do nothing 112 } 113 114 @Override 115 boolean isPowerStandbyOrTransient() { 116 return false; 117 } 118 }; 119 120 mHdmiControlService.setIoLooper(mMyLooper); 121 mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context)); 122 mHdmiControlService.setDeviceConfig(new FakeDeviceConfigWrapper()); 123 mNativeWrapper = new FakeNativeWrapper(); 124 mHdmiCecController = HdmiCecController.createWithNativeWrapper( 125 mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter()); 126 mHdmiControlService.setCecController(mHdmiCecController); 127 mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService)); 128 mHdmiControlService.initService(); 129 mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY); 130 mPowerManager = new FakePowerManagerWrapper(context); 131 mHdmiControlService.setPowerManager(mPowerManager); 132 mNativeWrapper.setPhysicalAddress(0x0000); 133 mTestLooper.dispatchAll(); 134 mHdmiCecLocalDeviceTv = mHdmiControlService.tv(); 135 mTvLogicalAddress = mHdmiCecLocalDeviceTv.getDeviceInfo().getLogicalAddress(); 136 mNativeWrapper.clearResultMessages(); 137 } 138 139 @Test noResponse_queryAgainOnce_emptyResult()140 public void noResponse_queryAgainOnce_emptyResult() { 141 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 142 mCallback); 143 action.start(); 144 mTestLooper.dispatchAll(); 145 assertThat(mSupportedSads).isNull(); 146 147 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 148 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 149 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 150 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 151 mNativeWrapper.clearResultMessages(); 152 mTestLooper.moveTimeForward(TIMEOUT_MS); 153 mTestLooper.dispatchAll(); 154 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 155 mTestLooper.moveTimeForward(TIMEOUT_MS); 156 mTestLooper.dispatchAll(); 157 158 assertThat(mSupportedSads).isNotNull(); 159 assertThat(mSupportedSads.size()).isEqualTo(0); 160 161 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 162 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 163 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 164 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 165 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 166 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 167 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 168 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 169 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 170 171 mTestLooper.moveTimeForward(TIMEOUT_MS); 172 mTestLooper.dispatchAll(); 173 mTestLooper.moveTimeForward(TIMEOUT_MS); 174 mTestLooper.dispatchAll(); 175 mTestLooper.moveTimeForward(TIMEOUT_MS); 176 mTestLooper.dispatchAll(); 177 mTestLooper.moveTimeForward(TIMEOUT_MS); 178 mTestLooper.dispatchAll(); 179 mTestLooper.moveTimeForward(TIMEOUT_MS); 180 mTestLooper.dispatchAll(); 181 mTestLooper.moveTimeForward(TIMEOUT_MS); 182 mTestLooper.dispatchAll(); 183 184 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2); 185 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3); 186 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4); 187 assertThat(mSupportedSads.size()).isEqualTo(0); 188 } 189 190 @Test unrecognizedOpcode_dontQueryAgain_emptyResult()191 public void unrecognizedOpcode_dontQueryAgain_emptyResult() { 192 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 193 mCallback); 194 action.start(); 195 mTestLooper.dispatchAll(); 196 assertThat(mSupportedSads).isNull(); 197 198 HdmiCecMessage unrecognizedOpcode = HdmiCecMessageBuilder.buildFeatureAbortCommand( 199 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, 200 Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR, 201 Constants.ABORT_UNRECOGNIZED_OPCODE); 202 203 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 204 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 205 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 206 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 207 action.processCommand(unrecognizedOpcode); 208 mTestLooper.dispatchAll(); 209 210 assertThat(mSupportedSads).isNotNull(); 211 assertThat(mSupportedSads.size()).isEqualTo(0); 212 213 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 214 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 215 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 216 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 217 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 218 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 219 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 220 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 221 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 222 223 mTestLooper.moveTimeForward(TIMEOUT_MS); 224 mTestLooper.dispatchAll(); 225 mTestLooper.moveTimeForward(TIMEOUT_MS); 226 mTestLooper.dispatchAll(); 227 mTestLooper.moveTimeForward(TIMEOUT_MS); 228 mTestLooper.dispatchAll(); 229 mTestLooper.moveTimeForward(TIMEOUT_MS); 230 mTestLooper.dispatchAll(); 231 mTestLooper.moveTimeForward(TIMEOUT_MS); 232 mTestLooper.dispatchAll(); 233 mTestLooper.moveTimeForward(TIMEOUT_MS); 234 mTestLooper.dispatchAll(); 235 236 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2); 237 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3); 238 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4); 239 assertThat(mSupportedSads.size()).isEqualTo(0); 240 } 241 242 @Test featureAbort_dontQueryAgain_emptyResult()243 public void featureAbort_dontQueryAgain_emptyResult() { 244 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 245 mCallback); 246 action.start(); 247 mTestLooper.dispatchAll(); 248 HdmiCecMessage featureAbort = HdmiCecMessageBuilder.buildFeatureAbortCommand( 249 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, 250 Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR, 251 Constants.ABORT_INVALID_OPERAND); 252 253 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 254 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 255 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 256 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 257 mNativeWrapper.clearResultMessages(); 258 action.processCommand(featureAbort); 259 mTestLooper.dispatchAll(); 260 261 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 262 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 263 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 264 assertThat(mNativeWrapper.getResultMessages()).contains(expected2); 265 mNativeWrapper.clearResultMessages(); 266 action.processCommand(featureAbort); 267 mTestLooper.dispatchAll(); 268 269 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 270 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 271 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 272 assertThat(mNativeWrapper.getResultMessages()).contains(expected3); 273 mNativeWrapper.clearResultMessages(); 274 action.processCommand(featureAbort); 275 mTestLooper.dispatchAll(); 276 277 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 278 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 279 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 280 assertThat(mNativeWrapper.getResultMessages()).contains(expected4); 281 action.processCommand(featureAbort); 282 mTestLooper.dispatchAll(); 283 284 assertThat(mSupportedSads.size()).isEqualTo(0); 285 } 286 287 @Test allSupported_completeResult()288 public void allSupported_completeResult() { 289 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 290 mCallback); 291 action.start(); 292 mTestLooper.dispatchAll(); 293 294 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 295 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 296 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 297 byte[] sadsToRespond_1 = new byte[]{ 298 0x0F, 0x18, 0x4A, 299 0x17, 0x64, 0x5A, 300 0x1F, 0x4B, 0x00, 301 0x27, 0x20, 0x0A}; 302 HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 303 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); 304 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 305 mNativeWrapper.clearResultMessages(); 306 action.processCommand(response1); 307 mTestLooper.dispatchAll(); 308 309 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 310 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 311 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 312 byte[] sadsToRespond_2 = new byte[]{ 313 0x2F, 0x18, 0x4A, 314 0x37, 0x64, 0x5A, 315 0x3F, 0x4B, 0x00, 316 0x47, 0x20, 0x0A}; 317 HdmiCecMessage response2 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 318 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_2); 319 assertThat(mNativeWrapper.getResultMessages()).contains(expected2); 320 mNativeWrapper.clearResultMessages(); 321 action.processCommand(response2); 322 mTestLooper.dispatchAll(); 323 324 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 325 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 326 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 327 byte[] sadsToRespond_3 = new byte[]{ 328 0x4F, 0x18, 0x4A, 329 0x57, 0x64, 0x5A, 330 0x5F, 0x4B, 0x00, 331 0x67, 0x20, 0x0A}; 332 HdmiCecMessage response3 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 333 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_3); 334 assertThat(mNativeWrapper.getResultMessages()).contains(expected3); 335 mNativeWrapper.clearResultMessages(); 336 action.processCommand(response3); 337 mTestLooper.dispatchAll(); 338 339 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 340 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 341 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 342 byte[] sadsToRespond_4 = new byte[]{ 343 0x6F, 0x18, 0x4A, 344 0x77, 0x64, 0x5A, 345 0x7F, 0x4B, 0x00}; 346 HdmiCecMessage response4 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 347 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_4); 348 assertThat(mNativeWrapper.getResultMessages()).contains(expected4); 349 action.processCommand(response4); 350 mTestLooper.dispatchAll(); 351 352 assertThat(mSupportedSads.size()).isEqualTo(15); 353 assertThat(Arrays.equals(sadsToRespond_1, 354 concatenateSads(mSupportedSads.subList(0, 4)))).isTrue(); 355 assertThat(Arrays.equals(sadsToRespond_2, 356 concatenateSads(mSupportedSads.subList(4, 8)))).isTrue(); 357 assertThat(Arrays.equals(sadsToRespond_3, 358 concatenateSads(mSupportedSads.subList(8, 12)))).isTrue(); 359 assertThat(Arrays.equals(sadsToRespond_4, 360 concatenateSads(mSupportedSads.subList(12, 15)))).isTrue(); 361 } 362 363 @Test subsetSupported_subsetResult()364 public void subsetSupported_subsetResult() { 365 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 366 mCallback); 367 action.start(); 368 mTestLooper.dispatchAll(); 369 370 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 371 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 372 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 373 byte[] sadsToRespond_1 = new byte[]{ 374 0x0F, 0x18, 0x4A, 375 0x1F, 0x4B, 0x00, 376 0x27, 0x20, 0x0A}; 377 HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 378 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); 379 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 380 mNativeWrapper.clearResultMessages(); 381 action.processCommand(response1); 382 mTestLooper.dispatchAll(); 383 384 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 385 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 386 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 387 byte[] sadsToRespond_2 = new byte[]{ 388 0x2F, 0x20, 0x0A}; 389 HdmiCecMessage response2 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 390 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_2); 391 assertThat(mNativeWrapper.getResultMessages()).contains(expected2); 392 mNativeWrapper.clearResultMessages(); 393 action.processCommand(response2); 394 mTestLooper.dispatchAll(); 395 396 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 397 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 398 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 399 byte[] sadsToRespond_3 = new byte[]{ 400 0x4F, 0x18, 0x4A, 401 0x57, 0x64, 0x5A, 402 0x5F, 0x4B, 0x00, 403 0x67, 0x20, 0x0A}; 404 HdmiCecMessage response3 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 405 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_3); 406 assertThat(mNativeWrapper.getResultMessages()).contains(expected3); 407 mNativeWrapper.clearResultMessages(); 408 action.processCommand(response3); 409 mTestLooper.dispatchAll(); 410 411 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 412 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 413 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 414 byte[] sadsToRespond_4 = new byte[]{ 415 0x7F, 0x4B, 0x00}; 416 HdmiCecMessage response4 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 417 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_4); 418 assertThat(mNativeWrapper.getResultMessages()).contains(expected4); 419 action.processCommand(response4); 420 mTestLooper.dispatchAll(); 421 422 assertThat(mSupportedSads.size()).isEqualTo(9); 423 assertThat(Arrays.equals(sadsToRespond_1, 424 concatenateSads(mSupportedSads.subList(0, 3)))).isTrue(); 425 assertThat(Arrays.equals(sadsToRespond_2, 426 concatenateSads(mSupportedSads.subList(3, 4)))).isTrue(); 427 assertThat(Arrays.equals(sadsToRespond_3, 428 concatenateSads(mSupportedSads.subList(4, 8)))).isTrue(); 429 assertThat(Arrays.equals(sadsToRespond_4, 430 concatenateSads(mSupportedSads.subList(8, 9)))).isTrue(); 431 } 432 433 @Test invalidCodecs_emptyResults()434 public void invalidCodecs_emptyResults() { 435 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 436 mCallback); 437 action.start(); 438 mTestLooper.dispatchAll(); 439 440 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 441 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 442 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 443 // Negative values require explicit casting 444 byte[] sadsToRespond_1 = new byte[]{ 445 (byte) 0x80, 0x18, 0x4A, 446 (byte) 0x82, 0x64, 0x5A, 447 (byte) 0x87, 0x4B, 0x00, 448 (byte) 0x8F, 0x20, 0x0A}; 449 HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 450 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); 451 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 452 mNativeWrapper.clearResultMessages(); 453 action.processCommand(response1); 454 mTestLooper.dispatchAll(); 455 456 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 457 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 458 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 459 byte[] sadsToRespond_2 = new byte[]{ 460 (byte) 0x92, 0x18, 0x4A, 461 (byte) 0x98, 0x64, 0x5A, 462 (byte) 0xA1, 0x4B, 0x00, 463 (byte) 0xA4, 0x20, 0x0A}; 464 HdmiCecMessage response2 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 465 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_2); 466 assertThat(mNativeWrapper.getResultMessages()).contains(expected2); 467 mNativeWrapper.clearResultMessages(); 468 action.processCommand(response2); 469 mTestLooper.dispatchAll(); 470 471 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 472 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 473 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 474 byte[] sadsToRespond_3 = new byte[]{ 475 (byte) 0xB3, 0x18, 0x4A, 476 (byte) 0xBA, 0x64, 0x5A, 477 (byte) 0xCB, 0x4B, 0x00, 478 (byte) 0xCF, 0x20, 0x0A}; 479 HdmiCecMessage response3 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 480 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_3); 481 assertThat(mNativeWrapper.getResultMessages()).contains(expected3); 482 mNativeWrapper.clearResultMessages(); 483 action.processCommand(response3); 484 mTestLooper.dispatchAll(); 485 486 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 487 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 488 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 489 byte[] sadsToRespond_4 = new byte[]{ 490 (byte) 0xF0, 0x18, 0x4A, 491 (byte) 0xF1, 0x64, 0x5A, 492 (byte) 0xF3, 0x4B, 0x00}; 493 HdmiCecMessage response4 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 494 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_4); 495 assertThat(mNativeWrapper.getResultMessages()).contains(expected4); 496 action.processCommand(response4); 497 mTestLooper.dispatchAll(); 498 499 assertThat(mSupportedSads.size()).isEqualTo(0); 500 } 501 502 @Test invalidMessageLength_queryAgainOnce()503 public void invalidMessageLength_queryAgainOnce() { 504 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 505 mCallback); 506 action.start(); 507 mTestLooper.dispatchAll(); 508 assertThat(mSupportedSads).isNull(); 509 510 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 511 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 512 CODECS_TO_QUERY_1.stream().mapToInt(i -> i).toArray()); 513 byte[] sadsToRespond_1 = new byte[]{ 514 0x0F, 0x18, 515 0x17, 0x64, 0x5A, 516 0x1F, 0x4B, 0x00, 517 0x27, 0x20, 0x0A}; 518 HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 519 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); 520 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 521 mNativeWrapper.clearResultMessages(); 522 action.processCommand(response1); 523 mTestLooper.dispatchAll(); 524 mTestLooper.moveTimeForward(TIMEOUT_MS); 525 mTestLooper.dispatchAll(); 526 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 527 mNativeWrapper.clearResultMessages(); 528 mTestLooper.moveTimeForward(TIMEOUT_MS); 529 mTestLooper.dispatchAll(); 530 531 assertThat(mSupportedSads).isNotNull(); 532 assertThat(mSupportedSads.size()).isEqualTo(0); 533 534 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 535 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 536 CODECS_TO_QUERY_2.stream().mapToInt(i -> i).toArray()); 537 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 538 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 539 CODECS_TO_QUERY_3.stream().mapToInt(i -> i).toArray()); 540 HdmiCecMessage expected4 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 541 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 542 CODECS_TO_QUERY_4.stream().mapToInt(i -> i).toArray()); 543 544 mTestLooper.moveTimeForward(TIMEOUT_MS); 545 mTestLooper.dispatchAll(); 546 mTestLooper.moveTimeForward(TIMEOUT_MS); 547 mTestLooper.dispatchAll(); 548 mTestLooper.moveTimeForward(TIMEOUT_MS); 549 mTestLooper.dispatchAll(); 550 mTestLooper.moveTimeForward(TIMEOUT_MS); 551 mTestLooper.dispatchAll(); 552 mTestLooper.moveTimeForward(TIMEOUT_MS); 553 mTestLooper.dispatchAll(); 554 mTestLooper.moveTimeForward(TIMEOUT_MS); 555 mTestLooper.dispatchAll(); 556 557 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected2); 558 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected3); 559 assertThat(mNativeWrapper.getResultMessages()).doesNotContain(expected4); 560 assertThat(mSupportedSads.size()).isEqualTo(0); 561 } 562 563 @Test selectedSads_allSupported_completeResult()564 public void selectedSads_allSupported_completeResult() { 565 mHdmiControlService.getHdmiCecConfig().setIntValue( 566 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_MPEG1, 567 HdmiControlManager.QUERY_SAD_DISABLED); 568 mHdmiControlService.getHdmiCecConfig().setIntValue( 569 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO, 570 HdmiControlManager.QUERY_SAD_DISABLED); 571 mHdmiControlService.getHdmiCecConfig().setIntValue( 572 HdmiControlManager.CEC_SETTING_NAME_QUERY_SAD_WMAPRO, 573 HdmiControlManager.QUERY_SAD_DISABLED); 574 RequestSadAction action = new RequestSadAction(mHdmiCecLocalDeviceTv, ADDR_AUDIO_SYSTEM, 575 mCallback); 576 action.start(); 577 mTestLooper.dispatchAll(); 578 579 HdmiCecMessage expected1 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 580 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 581 new int[]{Constants.AUDIO_CODEC_LPCM, Constants.AUDIO_CODEC_DD, 582 Constants.AUDIO_CODEC_MP3, Constants.AUDIO_CODEC_MPEG2}); 583 byte[] sadsToRespond_1 = new byte[]{ 584 0x0F, 0x18, 0x4A, 585 0x17, 0x64, 0x5A, 586 0x27, 0x20, 0x0A, 587 0x2F, 0x18, 0x4A}; 588 HdmiCecMessage response1 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 589 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_1); 590 assertThat(mNativeWrapper.getResultMessages()).contains(expected1); 591 mNativeWrapper.clearResultMessages(); 592 action.processCommand(response1); 593 mTestLooper.dispatchAll(); 594 595 HdmiCecMessage expected2 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 596 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 597 new int[]{Constants.AUDIO_CODEC_AAC, Constants.AUDIO_CODEC_DTS, 598 Constants.AUDIO_CODEC_ATRAC, Constants.AUDIO_CODEC_DDP}); 599 byte[] sadsToRespond_2 = new byte[]{ 600 0x37, 0x64, 0x5A, 601 0x3F, 0x4B, 0x00, 602 0x47, 0x20, 0x0A, 603 0x4F, 0x18, 0x4A}; 604 HdmiCecMessage response2 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 605 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_2); 606 assertThat(mNativeWrapper.getResultMessages()).contains(expected2); 607 mNativeWrapper.clearResultMessages(); 608 action.processCommand(response2); 609 mTestLooper.dispatchAll(); 610 611 HdmiCecMessage expected3 = HdmiCecMessageBuilder.buildRequestShortAudioDescriptor( 612 mTvLogicalAddress, Constants.ADDR_AUDIO_SYSTEM, 613 new int[]{Constants.AUDIO_CODEC_DTSHD, Constants.AUDIO_CODEC_TRUEHD, 614 Constants.AUDIO_CODEC_DST, Constants.AUDIO_CODEC_MAX}); 615 byte[] sadsToRespond_3 = new byte[]{ 616 0x5F, 0x4B, 0x00, 617 0x67, 0x20, 0x0A, 618 0x6F, 0x18, 0x4A, 619 0x7F, 0x4B, 0x00}; 620 HdmiCecMessage response3 = HdmiCecMessageBuilder.buildReportShortAudioDescriptor( 621 Constants.ADDR_AUDIO_SYSTEM, mTvLogicalAddress, sadsToRespond_3); 622 assertThat(mNativeWrapper.getResultMessages()).contains(expected3); 623 mNativeWrapper.clearResultMessages(); 624 action.processCommand(response3); 625 mTestLooper.dispatchAll(); 626 627 assertThat(mSupportedSads.size()).isEqualTo(12); 628 assertThat(Arrays.equals(sadsToRespond_1, 629 concatenateSads(mSupportedSads.subList(0, 4)))).isTrue(); 630 assertThat(Arrays.equals(sadsToRespond_2, 631 concatenateSads(mSupportedSads.subList(4, 8)))).isTrue(); 632 assertThat(Arrays.equals(sadsToRespond_3, 633 concatenateSads(mSupportedSads.subList(8, 12)))).isTrue(); 634 } 635 } 636