1 /* 2 * Copyright (C) 2024 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.car.audio; 18 19 import static android.car.media.CarAudioManager.PRIMARY_AUDIO_ZONE; 20 import static android.media.AudioManager.GET_DEVICES_INPUTS; 21 import static android.media.AudioManager.GET_DEVICES_OUTPUTS; 22 23 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.MEDIA_TEST_DEVICE; 24 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.NAVIGATION_TEST_DEVICE; 25 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.PRIMARY_ZONE_MICROPHONE_DEVICE; 26 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.SECONDARY_ZONE_BUS_1000_INPUT_DEVICE; 27 import static com.android.car.audio.CarAudioTestUtils.GAINS; 28 import static com.android.car.audio.CarAudioTestUtils.SECONDARY_ZONE_ID; 29 import static com.android.car.audio.CarAudioTestUtils.TEST_CREATED_CAR_AUDIO_CONTEXT; 30 import static com.android.car.audio.CarAudioTestUtils.createAudioPort; 31 import static com.android.car.audio.CarAudioTestUtils.createAudioPortDeviceExt; 32 import static com.android.car.audio.CarAudioTestUtils.createPrimaryAudioZone; 33 import static com.android.car.audio.CarAudioTestUtils.createSecondaryAudioZone; 34 import static com.android.car.audio.CoreAudioRoutingUtils.getCoreAudioZone; 35 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 36 37 import static com.google.common.truth.Truth.assertWithMessage; 38 39 import static org.junit.Assert.assertThrows; 40 import static org.mockito.Mockito.when; 41 42 import android.car.test.mocks.AbstractExtendedMockitoTestCase; 43 import android.hardware.automotive.audiocontrol.AudioDeviceConfiguration; 44 import android.hardware.automotive.audiocontrol.AudioZone; 45 import android.hardware.automotive.audiocontrol.RoutingDeviceConfiguration; 46 import android.media.AudioDeviceAttributes; 47 import android.media.audio.common.AudioDeviceType; 48 import android.media.audio.common.AudioPort; 49 import android.media.audio.common.AudioPortDeviceExt; 50 51 import com.android.car.audio.hal.AudioControlWrapper; 52 import com.android.car.internal.util.LocalLog; 53 54 import org.junit.Before; 55 import org.junit.Test; 56 import org.junit.runner.RunWith; 57 import org.mockito.Mock; 58 import org.mockito.junit.MockitoJUnitRunner; 59 60 import java.util.ArrayList; 61 import java.util.List; 62 63 @RunWith(MockitoJUnitRunner.class) 64 public final class CarAudioZonesHelperAudioControlHALUnitTest 65 extends AbstractExtendedMockitoTestCase { 66 67 private static final int TEST_PRIMARY_ZONE_OCCUPANT_ID = 1; 68 private static final int TEST_SECONDARY_ZONE_OCCUPANT_ID = 2; 69 70 @Mock 71 private CarAudioSettings mCarAudioSettings; 72 @Mock 73 private AudioManagerWrapper mAudioManager; 74 @Mock 75 private LocalLog mServiceLog; 76 @Mock 77 private AudioControlWrapper mAudioControlWrapper; 78 private boolean mUseAudioFadeManager = true; 79 80 private final List<AudioZone> mHALAudioZones = new ArrayList<>(); 81 82 private final CarAudioDeviceInfoTestUtils mDeviceTestUtils = new CarAudioDeviceInfoTestUtils(); 83 private final AudioDeviceConfiguration mAudioDeviceConfig = new AudioDeviceConfiguration(); 84 private final List<AudioPort> mMirrorPorts = new ArrayList<>(); 85 86 @Override clearInlineMocks(String when)87 protected void clearInlineMocks(String when) { 88 super.clearInlineMocks(when); 89 } 90 91 @Override onSessionBuilder(CustomMockitoSessionBuilder session)92 protected void onSessionBuilder(CustomMockitoSessionBuilder session) { 93 session.spyStatic(AudioManagerWrapper.class); 94 } 95 96 @Before setUp()97 public void setUp() { 98 doReturn(CoreAudioRoutingUtils.getProductStrategies()) 99 .when(AudioManagerWrapper::getAudioProductStrategies); 100 101 var outputDevice = mDeviceTestUtils.generateOutputDeviceInfos(); 102 var inputDevices = mDeviceTestUtils.generateInputDeviceInfos(); 103 when(mAudioManager.getDevices(GET_DEVICES_OUTPUTS)).thenReturn(outputDevice); 104 when(mAudioManager.getDevices(GET_DEVICES_INPUTS)).thenReturn(inputDevices); 105 106 when(mAudioControlWrapper.supportsFeature( 107 AudioControlWrapper.AUDIOCONTROL_FEATURE_AUDIO_CONFIGURATION)).thenReturn(true); 108 when(mAudioControlWrapper.getCarAudioZones()).thenReturn(mHALAudioZones); 109 mAudioDeviceConfig.routingConfig = RoutingDeviceConfiguration.DYNAMIC_AUDIO_ROUTING; 110 when(mAudioControlWrapper.getAudioDeviceConfiguration()).thenReturn(mAudioDeviceConfig); 111 when(mAudioControlWrapper.getOutputMirroringDevices()).thenReturn(mMirrorPorts); 112 } 113 114 @Test constructor_withNullAudioControlHAL()115 public void constructor_withNullAudioControlHAL() { 116 AudioControlWrapper audioControl = null; 117 118 var thrown = assertThrows(NullPointerException.class, 119 () -> new CarAudioZonesHelperAudioControlHAL(audioControl, mAudioManager, 120 mCarAudioSettings, mServiceLog, mUseAudioFadeManager)); 121 122 expectWithMessage("Exception for null audio control HAL").that(thrown) 123 .hasMessageThat().contains("Audio control HAL"); 124 } 125 126 @Test constructor_withNullAudioManager()127 public void constructor_withNullAudioManager() { 128 AudioManagerWrapper audioManager = null; 129 130 var thrown = assertThrows(NullPointerException.class, 131 () -> new CarAudioZonesHelperAudioControlHAL(mAudioControlWrapper, audioManager, 132 mCarAudioSettings, mServiceLog, mUseAudioFadeManager)); 133 134 expectWithMessage("Exception for null audio manager").that(thrown) 135 .hasMessageThat().contains("Audio manager"); 136 } 137 138 @Test constructor_withNullAudioSettings()139 public void constructor_withNullAudioSettings() { 140 CarAudioSettings audioSettings = null; 141 142 var thrown = assertThrows(NullPointerException.class, 143 () -> new CarAudioZonesHelperAudioControlHAL(mAudioControlWrapper, mAudioManager, 144 audioSettings, mServiceLog, mUseAudioFadeManager)); 145 146 expectWithMessage("Exception for null car audio settings").that(thrown) 147 .hasMessageThat().contains("Car audio settings"); 148 } 149 150 @Test constructor_withNullServiceLogs()151 public void constructor_withNullServiceLogs() { 152 LocalLog serviceLogs = null; 153 154 var thrown = assertThrows(NullPointerException.class, 155 () -> new CarAudioZonesHelperAudioControlHAL(mAudioControlWrapper, mAudioManager, 156 mCarAudioSettings, serviceLogs, mUseAudioFadeManager)); 157 158 expectWithMessage("Exception for null car audio logs").that(thrown) 159 .hasMessageThat().contains("Car audio log"); 160 } 161 162 @Test loadAudioZones_withUnsupportedOperationFromHal()163 public void loadAudioZones_withUnsupportedOperationFromHal() { 164 when(mAudioControlWrapper.supportsFeature( 165 AudioControlWrapper.AUDIOCONTROL_FEATURE_AUDIO_CONFIGURATION)).thenReturn(false); 166 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 167 168 var audioZones = helper.loadAudioZones(); 169 170 expectWithMessage("Loaded audio zones with unsupported feature from HAL") 171 .that(audioZones.size()).isEqualTo(0); 172 } 173 174 @Test loadAudioZones_withDefaultDeviceConfig()175 public void loadAudioZones_withDefaultDeviceConfig() { 176 mAudioDeviceConfig.routingConfig = RoutingDeviceConfiguration.DEFAULT_AUDIO_ROUTING; 177 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 178 179 var audioZones = helper.loadAudioZones(); 180 181 expectWithMessage("Loaded audio zones with default audio routing") 182 .that(audioZones.size()).isEqualTo(0); 183 } 184 185 @Test loadAudioZones_withNullZonesFromHal()186 public void loadAudioZones_withNullZonesFromHal() { 187 when(mAudioControlWrapper.getCarAudioZones()).thenReturn(null); 188 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 189 190 var audioZones = helper.loadAudioZones(); 191 192 expectWithMessage("Loaded audio zones with null audio zones from HAL") 193 .that(audioZones.size()).isEqualTo(0); 194 } 195 196 @Test loadAudioZones_withEmptyZonesFromHal()197 public void loadAudioZones_withEmptyZonesFromHal() { 198 mHALAudioZones.clear(); 199 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 200 201 var audioZones = helper.loadAudioZones(); 202 203 expectWithMessage("Loaded audio zones with null audio zones from HAL") 204 .that(audioZones.size()).isEqualTo(0); 205 } 206 207 @Test loadAudioZones_withNullZoneInZonesFromHal()208 public void loadAudioZones_withNullZoneInZonesFromHal() { 209 mHALAudioZones.add(null); 210 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 211 212 var audioZones = helper.loadAudioZones(); 213 214 expectWithMessage("Loaded audio zones with null audio zone in audio zones from HAL") 215 .that(audioZones.size()).isEqualTo(0); 216 } 217 218 @Test loadAudioZones_withRepeatingZonesFromHal()219 public void loadAudioZones_withRepeatingZonesFromHal() { 220 mHALAudioZones.add(createPrimaryAudioZone()); 221 mHALAudioZones.add(createPrimaryAudioZone()); 222 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 223 224 var audioZones = helper.loadAudioZones(); 225 226 expectWithMessage("Loaded audio zones with repeating audio zones from HAL") 227 .that(audioZones.size()).isEqualTo(0); 228 } 229 230 @Test loadAudioZones_withValidPrimaryZonesFromHal()231 public void loadAudioZones_withValidPrimaryZonesFromHal() { 232 mHALAudioZones.add(createPrimaryAudioZone()); 233 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 234 235 var audioZones = helper.loadAudioZones(); 236 237 expectWithMessage("Loaded audio zones with valid primary zone from HAL") 238 .that(audioZones.size()).isEqualTo(1); 239 var primaryZone = audioZones.get(PRIMARY_AUDIO_ZONE); 240 assertWithMessage("Loaded primary audio zone").that(primaryZone).isNotNull(); 241 expectWithMessage("Loaded primary audio zone configs") 242 .that(primaryZone.getAllCarAudioZoneConfigs()).hasSize(3); 243 var inputAddresses = primaryZone.getInputAudioDevices().stream() 244 .map(AudioDeviceAttributes::getAddress).toList(); 245 expectWithMessage("Loaded primary zone input devices").that(inputAddresses) 246 .containsExactly(PRIMARY_ZONE_MICROPHONE_DEVICE, 247 SECONDARY_ZONE_BUS_1000_INPUT_DEVICE); 248 } 249 250 @Test loadAudioZones_withValidSecondaryZoneFromHal()251 public void loadAudioZones_withValidSecondaryZoneFromHal() { 252 mHALAudioZones.add(createPrimaryAudioZone()); 253 mHALAudioZones.add(createSecondaryAudioZone()); 254 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 255 256 var audioZones = helper.loadAudioZones(); 257 258 expectWithMessage("Loaded audio zones with valid secondary zone from HAL") 259 .that(audioZones.size()).isEqualTo(2); 260 var secondaryZone = audioZones.get(SECONDARY_ZONE_ID); 261 assertWithMessage("Loaded secondary audio zone").that(secondaryZone).isNotNull(); 262 expectWithMessage("Loaded secondary audio zone configs") 263 .that(secondaryZone.getAllCarAudioZoneConfigs()).hasSize(2); 264 } 265 266 @Test loadAudioZones_withoutPrimaryZoneFromHal()267 public void loadAudioZones_withoutPrimaryZoneFromHal() { 268 mHALAudioZones.add(createSecondaryAudioZone()); 269 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 270 271 var audioZones = helper.loadAudioZones(); 272 273 expectWithMessage("Loaded audio zones without primary zone") 274 .that(audioZones.size()).isEqualTo(0); 275 } 276 277 @Test loadAudioZones_withInvalidUseCoreVolumeConfiguration()278 public void loadAudioZones_withInvalidUseCoreVolumeConfiguration() { 279 mHALAudioZones.add(createPrimaryAudioZone()); 280 mAudioDeviceConfig.useCoreAudioVolume = true; 281 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 282 283 var audioZones = helper.loadAudioZones(); 284 285 expectWithMessage("Loaded audio zones with invalid use core volume configuration") 286 .that(audioZones.size()).isEqualTo(0); 287 } 288 289 @Test loadAudioZones_withCoreAudioRoutingAndValidPrimaryZonesFromHal()290 public void loadAudioZones_withCoreAudioRoutingAndValidPrimaryZonesFromHal() { 291 mHALAudioZones.add(getCoreAudioZone()); 292 mAudioDeviceConfig.routingConfig = 293 RoutingDeviceConfiguration.CONFIGURABLE_AUDIO_ENGINE_ROUTING; 294 mAudioDeviceConfig.useCoreAudioVolume = true; 295 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 296 297 var audioZones = helper.loadAudioZones(); 298 299 expectWithMessage("Loaded audio zones with core audio routing") 300 .that(audioZones.size()).isEqualTo(1); 301 var primaryZone = audioZones.get(PRIMARY_AUDIO_ZONE); 302 assertWithMessage("Loaded primary audio zone with core audio routing") 303 .that(primaryZone).isNotNull(); 304 expectWithMessage("Loaded primary audio zone configs with core audio routing") 305 .that(primaryZone.getAllCarAudioZoneConfigs()).hasSize(1); 306 } 307 308 @Test getCarAudioZoneIdToOccupantZoneIdMapping_withPrimaryZoneMapped()309 public void getCarAudioZoneIdToOccupantZoneIdMapping_withPrimaryZoneMapped() { 310 var primaryZone = createPrimaryAudioZone(); 311 primaryZone.occupantZoneId = TEST_PRIMARY_ZONE_OCCUPANT_ID; 312 mHALAudioZones.add(primaryZone); 313 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 314 helper.loadAudioZones(); 315 316 var audioZoneIdToOccupantZoneId = helper.getCarAudioZoneIdToOccupantZoneIdMapping(); 317 318 expectWithMessage("Loaded audio zones to occupant zone mapping") 319 .that(audioZoneIdToOccupantZoneId.size()).isEqualTo(1); 320 expectWithMessage("Loaded primary occupant zone mapping").that(audioZoneIdToOccupantZoneId 321 .get(PRIMARY_AUDIO_ZONE)).isEqualTo(TEST_PRIMARY_ZONE_OCCUPANT_ID); 322 } 323 324 @Test getCarAudioZoneIdToOccupantZoneIdMapping_withPrimaryAndSecondaryZoneMapped()325 public void getCarAudioZoneIdToOccupantZoneIdMapping_withPrimaryAndSecondaryZoneMapped() { 326 var primaryZone = createPrimaryAudioZone(); 327 primaryZone.occupantZoneId = TEST_PRIMARY_ZONE_OCCUPANT_ID; 328 var secondaryZone = createSecondaryAudioZone(); 329 secondaryZone.occupantZoneId = TEST_SECONDARY_ZONE_OCCUPANT_ID; 330 mHALAudioZones.add(primaryZone); 331 mHALAudioZones.add(secondaryZone); 332 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 333 helper.loadAudioZones(); 334 335 var audioZoneIdToOccupantZoneId = helper.getCarAudioZoneIdToOccupantZoneIdMapping(); 336 337 expectWithMessage("Loaded audio zones to occupant zone mapping with primary and secondary" 338 + " zones").that(audioZoneIdToOccupantZoneId.size()).isEqualTo(2); 339 expectWithMessage("Loaded primary occupant zone with both primary and secondary zones") 340 .that(audioZoneIdToOccupantZoneId.get(PRIMARY_AUDIO_ZONE)) 341 .isEqualTo(TEST_PRIMARY_ZONE_OCCUPANT_ID); 342 expectWithMessage("Loaded secondary occupant zone mapping with both primary and secondary" 343 + " zones").that(audioZoneIdToOccupantZoneId.get(SECONDARY_ZONE_ID)) 344 .isEqualTo(TEST_SECONDARY_ZONE_OCCUPANT_ID); 345 } 346 347 @Test getCarAudioZoneIdToOccupantZoneIdMapping_withLoadFailures()348 public void getCarAudioZoneIdToOccupantZoneIdMapping_withLoadFailures() { 349 var secondaryZone = createSecondaryAudioZone(); 350 secondaryZone.occupantZoneId = TEST_SECONDARY_ZONE_OCCUPANT_ID; 351 mHALAudioZones.add(secondaryZone); 352 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 353 helper.loadAudioZones(); 354 355 var audioZoneIdToOccupantZoneId = helper.getCarAudioZoneIdToOccupantZoneIdMapping(); 356 357 expectWithMessage("Loaded audio zones to occupant zone mapping with load zones failure") 358 .that(audioZoneIdToOccupantZoneId.size()).isEqualTo(0); 359 } 360 361 @Test getCarAudioContext_withPrimaryZoneFromHal()362 public void getCarAudioContext_withPrimaryZoneFromHal() { 363 mHALAudioZones.add(createPrimaryAudioZone()); 364 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 365 helper.loadAudioZones(); 366 367 var carAudioContext = helper.getCarAudioContext(); 368 369 expectWithMessage("Loaded car audio context with primary zone") 370 .that(carAudioContext).isEqualTo(TEST_CREATED_CAR_AUDIO_CONTEXT); 371 } 372 373 @Test getCarAudioContext_withoutPrimaryZoneFromHal()374 public void getCarAudioContext_withoutPrimaryZoneFromHal() { 375 mHALAudioZones.add(createSecondaryAudioZone()); 376 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 377 helper.loadAudioZones(); 378 379 var carAudioContext = helper.getCarAudioContext(); 380 381 expectWithMessage("Loaded car audio context without primary zone") 382 .that(carAudioContext).isNull(); 383 } 384 385 @Test getCarAudioContext_withoutCallingLoadZonesFirst()386 public void getCarAudioContext_withoutCallingLoadZonesFirst() { 387 mHALAudioZones.add(createPrimaryAudioZone()); 388 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 389 390 var carAudioContext = helper.getCarAudioContext(); 391 392 expectWithMessage("Loaded car audio context without initializing helper") 393 .that(carAudioContext).isNull(); 394 } 395 396 @Test useCoreAudioRouting_withoutCallingLoadZonesFirst()397 public void useCoreAudioRouting_withoutCallingLoadZonesFirst() { 398 mHALAudioZones.add(createPrimaryAudioZone()); 399 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 400 401 expectWithMessage("Loaded car audio routing without initializing helper") 402 .that(helper.useCoreAudioRouting()).isFalse(); 403 } 404 405 @Test useCoreAudioRouting_withUseDynamicRoutingFromHal()406 public void useCoreAudioRouting_withUseDynamicRoutingFromHal() { 407 mAudioDeviceConfig.routingConfig = RoutingDeviceConfiguration.DYNAMIC_AUDIO_ROUTING; 408 mHALAudioZones.add(createSecondaryAudioZone()); 409 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 410 helper.loadAudioZones(); 411 412 expectWithMessage("Loaded car audio routing with dynamic audio routing") 413 .that(helper.useCoreAudioRouting()).isFalse(); 414 } 415 416 @Test useCoreAudioRouting_withCoreAudioRoutingFromHal()417 public void useCoreAudioRouting_withCoreAudioRoutingFromHal() { 418 mHALAudioZones.add(getCoreAudioZone()); 419 mAudioDeviceConfig.routingConfig = 420 RoutingDeviceConfiguration.CONFIGURABLE_AUDIO_ENGINE_ROUTING; 421 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 422 helper.loadAudioZones(); 423 424 expectWithMessage("Loaded car audio routing with core audio routing") 425 .that(helper.useCoreAudioRouting()).isTrue(); 426 } 427 428 @Test useCoreAudioRouting_withCoreAudioRoutingFromHalAndLoadFailure()429 public void useCoreAudioRouting_withCoreAudioRoutingFromHalAndLoadFailure() { 430 mHALAudioZones.add(createSecondaryAudioZone()); 431 mAudioDeviceConfig.routingConfig = 432 RoutingDeviceConfiguration.CONFIGURABLE_AUDIO_ENGINE_ROUTING; 433 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 434 helper.loadAudioZones(); 435 436 expectWithMessage("Loaded car audio routing with core audio routing and load failure") 437 .that(helper.useCoreAudioRouting()).isFalse(); 438 } 439 440 @Test useCoreAudioVolume_withoutCallingLoadZonesFirst()441 public void useCoreAudioVolume_withoutCallingLoadZonesFirst() { 442 mHALAudioZones.add(createPrimaryAudioZone()); 443 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 444 445 expectWithMessage("Loaded car audio volume without initializing helper") 446 .that(helper.useCoreAudioVolume()).isFalse(); 447 } 448 449 @Test useCoreAudioVolume_withoutUseCoreVolumeFromHal()450 public void useCoreAudioVolume_withoutUseCoreVolumeFromHal() { 451 mAudioDeviceConfig.useCoreAudioVolume = false; 452 mHALAudioZones.add(createSecondaryAudioZone()); 453 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 454 helper.loadAudioZones(); 455 456 expectWithMessage("Loaded car audio volume without use core volume") 457 .that(helper.useCoreAudioVolume()).isFalse(); 458 } 459 460 @Test useCoreAudioVolume_withUseCoreVolumeFromHal()461 public void useCoreAudioVolume_withUseCoreVolumeFromHal() { 462 mAudioDeviceConfig.useCoreAudioVolume = true; 463 mHALAudioZones.add(getCoreAudioZone()); 464 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 465 helper.loadAudioZones(); 466 467 expectWithMessage("Loaded car audio volume with use core volume") 468 .that(helper.useCoreAudioVolume()).isTrue(); 469 } 470 471 @Test useCoreAudioVolume_withUseCoreVolumeFromHalAndLoadFailure()472 public void useCoreAudioVolume_withUseCoreVolumeFromHalAndLoadFailure() { 473 mAudioDeviceConfig.useCoreAudioVolume = true; 474 mHALAudioZones.add(createSecondaryAudioZone()); 475 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 476 helper.loadAudioZones(); 477 478 expectWithMessage("Loaded car audio volume with use core volume and load failure") 479 .that(helper.useCoreAudioVolume()).isFalse(); 480 } 481 482 @Test useVolumeGroupMuting_withoutCallingLoadZonesFirst()483 public void useVolumeGroupMuting_withoutCallingLoadZonesFirst() { 484 mHALAudioZones.add(createPrimaryAudioZone()); 485 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 486 487 expectWithMessage("Loaded car audio volume muting without initializing helper") 488 .that(helper.useVolumeGroupMuting()).isFalse(); 489 } 490 491 @Test useVolumeGroupMuting_withoutUseVolumeGroupMutingFromHal()492 public void useVolumeGroupMuting_withoutUseVolumeGroupMutingFromHal() { 493 mAudioDeviceConfig.useCarVolumeGroupMuting = false; 494 mHALAudioZones.add(createPrimaryAudioZone()); 495 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 496 helper.loadAudioZones(); 497 498 expectWithMessage("Loaded car audio volume muting without use volume muting") 499 .that(helper.useVolumeGroupMuting()).isFalse(); 500 } 501 502 @Test useVolumeGroupMuting_withUseVolumeGroupMutingFromHal()503 public void useVolumeGroupMuting_withUseVolumeGroupMutingFromHal() { 504 mAudioDeviceConfig.useCarVolumeGroupMuting = true; 505 mHALAudioZones.add(createPrimaryAudioZone()); 506 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 507 helper.loadAudioZones(); 508 509 expectWithMessage("Loaded car audio volume muting with use volume muting") 510 .that(helper.useVolumeGroupMuting()).isTrue(); 511 } 512 513 @Test useVolumeGroupMuting_withUseVolumeGroupMutingFromHalAndLoadFailure()514 public void useVolumeGroupMuting_withUseVolumeGroupMutingFromHalAndLoadFailure() { 515 mAudioDeviceConfig.useCarVolumeGroupMuting = true; 516 mHALAudioZones.add(createSecondaryAudioZone()); 517 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 518 helper.loadAudioZones(); 519 520 expectWithMessage("Loaded car audio volume muting with use volume muting and load failure") 521 .that(helper.useVolumeGroupMuting()).isFalse(); 522 } 523 524 @Test useHalDuckingSignalOrDefault_withoutCallingLoadZonesFirst()525 public void useHalDuckingSignalOrDefault_withoutCallingLoadZonesFirst() { 526 mAudioDeviceConfig.useHalDuckingSignals = true; 527 mHALAudioZones.add(createPrimaryAudioZone()); 528 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 529 530 boolean useHalDucking = helper.useHalDuckingSignalOrDefault( 531 /* unusedDefaultUseHalDuckingSignal= */ true); 532 533 expectWithMessage("Loaded HAL ducking without initializing helper").that(useHalDucking) 534 .isFalse(); 535 } 536 537 @Test useHalDuckingSignalOrDefault_withoutUseHalDuckingFromHal()538 public void useHalDuckingSignalOrDefault_withoutUseHalDuckingFromHal() { 539 mAudioDeviceConfig.useHalDuckingSignals = false; 540 mHALAudioZones.add(createPrimaryAudioZone()); 541 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 542 helper.loadAudioZones(); 543 544 boolean useHalDucking = helper.useHalDuckingSignalOrDefault( 545 /* unusedDefaultUseHalDuckingSignal= */ true); 546 547 expectWithMessage("Loaded HAL ducking without use HAL ducking").that(useHalDucking) 548 .isFalse(); 549 } 550 551 @Test useHalDuckingSignalOrDefault_withUseHalDuckingFromHal()552 public void useHalDuckingSignalOrDefault_withUseHalDuckingFromHal() { 553 mAudioDeviceConfig.useHalDuckingSignals = true; 554 mHALAudioZones.add(createPrimaryAudioZone()); 555 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 556 helper.loadAudioZones(); 557 558 boolean useHalDucking = helper.useHalDuckingSignalOrDefault( 559 /* unusedDefaultUseHalDuckingSignal= */ true); 560 561 expectWithMessage("Loaded HAL ducking with use HAL ducking").that(useHalDucking).isTrue(); 562 } 563 564 @Test useHalDuckingSignalOrDefault_withUseHalDuckingFromHalAndOverwriteFromParameter()565 public void useHalDuckingSignalOrDefault_withUseHalDuckingFromHalAndOverwriteFromParameter() { 566 mAudioDeviceConfig.useHalDuckingSignals = true; 567 mHALAudioZones.add(createPrimaryAudioZone()); 568 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 569 helper.loadAudioZones(); 570 571 boolean useHalDucking = helper.useHalDuckingSignalOrDefault( 572 /* unusedDefaultUseHalDuckingSignal= */ false); 573 574 expectWithMessage("Loaded HAL ducking with use HAL ducking and false overwritten from " 575 + "parameter").that(useHalDucking).isTrue(); 576 } 577 578 @Test useHalDuckingSignalOrDefault_withUseHalDuckingFromHalAndLoadFailure()579 public void useHalDuckingSignalOrDefault_withUseHalDuckingFromHalAndLoadFailure() { 580 mAudioDeviceConfig.useHalDuckingSignals = true; 581 mHALAudioZones.add(createSecondaryAudioZone()); 582 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 583 helper.loadAudioZones(); 584 585 boolean useHalDucking = helper.useHalDuckingSignalOrDefault( 586 /* unusedDefaultUseHalDuckingSignal= */ true); 587 588 expectWithMessage("Loaded HAL ducking with use HAL ducking and load failure") 589 .that(useHalDucking).isFalse(); 590 } 591 592 @Test getMirrorDeviceInfos_withNullPortList()593 public void getMirrorDeviceInfos_withNullPortList() { 594 when(mAudioControlWrapper.getOutputMirroringDevices()).thenReturn(null); 595 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 596 597 expectWithMessage("Converted output mirror devices for null ports list") 598 .that(helper.getMirrorDeviceInfos()).isEmpty(); 599 } 600 601 @Test getMirrorDeviceInfos_withEmptyPortList()602 public void getMirrorDeviceInfos_withEmptyPortList() { 603 mMirrorPorts.clear(); 604 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 605 606 expectWithMessage("Converted output mirror devices for empty ports list") 607 .that(helper.getMirrorDeviceInfos()).isEmpty(); 608 } 609 610 @Test getMirrorDeviceInfos_withValidPortList()611 public void getMirrorDeviceInfos_withValidPortList() { 612 AudioPortDeviceExt navPortDevice = 613 createAudioPortDeviceExt(AudioDeviceType.OUT_BUS, "", NAVIGATION_TEST_DEVICE); 614 AudioPort navPort = createAudioPort(2, "nav port", GAINS, navPortDevice); 615 AudioPortDeviceExt mediaPortDevice = 616 createAudioPortDeviceExt(AudioDeviceType.OUT_BUS, "", MEDIA_TEST_DEVICE); 617 AudioPort mediaPort = createAudioPort(1, "media port", GAINS, mediaPortDevice); 618 mMirrorPorts.add(mediaPort); 619 mMirrorPorts.add(navPort); 620 CarAudioZonesHelperAudioControlHAL helper = createAudioZonesHelper(); 621 622 var mirroringDevices = helper.getMirrorDeviceInfos(); 623 624 expectWithMessage("Converted output mirror devices for valid ports list") 625 .that(mirroringDevices).hasSize(2); 626 var addresses = mirroringDevices.stream().map(CarAudioDeviceInfo::getAddress).toList(); 627 expectWithMessage("Converted output mirror device addresses").that(addresses) 628 .containsExactly(NAVIGATION_TEST_DEVICE, MEDIA_TEST_DEVICE); 629 } 630 createAudioZonesHelper()631 private CarAudioZonesHelperAudioControlHAL createAudioZonesHelper() { 632 return new CarAudioZonesHelperAudioControlHAL(mAudioControlWrapper, mAudioManager, 633 mCarAudioSettings, mServiceLog, mUseAudioFadeManager); 634 } 635 } 636