1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.car.media; 18 19 import static android.car.media.CarAudioManager.AUDIO_FEATURE_DYNAMIC_ROUTING; 20 import static android.car.media.CarAudioManager.CONFIG_STATUS_CHANGED; 21 import static android.car.media.CarAudioManager.PRIMARY_AUDIO_ZONE; 22 import static android.media.AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; 23 import static android.media.AudioAttributes.USAGE_GAME; 24 import static android.media.AudioAttributes.USAGE_MEDIA; 25 import static android.media.AudioDeviceInfo.TYPE_BUILTIN_MIC; 26 import static android.media.AudioDeviceInfo.TYPE_FM_TUNER; 27 28 import static org.junit.Assert.assertThrows; 29 import static org.mockito.ArgumentMatchers.any; 30 import static org.mockito.ArgumentMatchers.anyString; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.Mockito.clearInvocations; 33 import static org.mockito.Mockito.doAnswer; 34 import static org.mockito.Mockito.doThrow; 35 import static org.mockito.Mockito.mock; 36 import static org.mockito.Mockito.never; 37 import static org.mockito.Mockito.timeout; 38 import static org.mockito.Mockito.verify; 39 import static org.mockito.Mockito.when; 40 41 import android.car.CarOccupantZoneManager.OccupantZoneInfo; 42 import android.car.test.AbstractExpectableTestCase; 43 import android.content.Context; 44 import android.media.AudioAttributes; 45 import android.media.AudioDeviceAttributes; 46 import android.media.AudioDeviceInfo; 47 import android.media.AudioManager; 48 import android.os.Handler; 49 import android.os.HandlerThread; 50 import android.os.IBinder; 51 import android.os.RemoteException; 52 import android.platform.test.ravenwood.RavenwoodRule; 53 54 import com.android.car.audio.AudioDeviceInfoBuilder; 55 import com.android.car.internal.ICarBase; 56 57 import org.junit.After; 58 import org.junit.Before; 59 import org.junit.Rule; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 import org.mockito.ArgumentCaptor; 63 import org.mockito.Mock; 64 import org.mockito.junit.MockitoJUnitRunner; 65 66 import java.util.List; 67 import java.util.concurrent.CountDownLatch; 68 import java.util.concurrent.Executor; 69 import java.util.concurrent.TimeUnit; 70 71 @RunWith(MockitoJUnitRunner.class) 72 public final class CarAudioManagerUnitTest extends AbstractExpectableTestCase { 73 // Required to set the process ID and set the "main" thread for this test, otherwise 74 // getMainLooper will return null. 75 @Rule 76 public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder().setProcessApp() 77 .setProvideMainThread(true).build(); 78 79 private static final String Car_AUDIO_MANAGER_TEST_THREAD_NAME = "CarAudioManagerUnitTest"; 80 private static final String MICROPHONE_ADDRESS = "Built-In Mic"; 81 private static final String FM_TUNER_ADDRESS = "FM Tuner"; 82 private static final String MEDIA_TEST_DEVICE = "media_bus_device"; 83 private static final String NAVIGATION_TEST_DEVICE = "navigation_bus_device"; 84 private static final int TEST_REAR_LEFT_ZONE_ID = 1; 85 private static final int TEST_REAR_RIGHT_ZONE_ID = 2; 86 private static final int TEST_FRONT_ZONE_ID = 3; 87 private static final int TEST_VOLUME_GROUP_ID = 1; 88 private static final int TEST_VOLUME_GROUP_INDEX = 10; 89 private static final int TEST_FLAGS = 0; 90 private static final int TEST_GAIN_MIN_VALUE = -3000; 91 private static final int TEST_GAIN_MAX_VALUE = -1000; 92 private static final int TEST_GAIN_DEFAULT_VALUE = -2000; 93 private static final int TEST_VOLUME_GROUP_COUNT = 2; 94 private static final int TEST_USAGE = USAGE_MEDIA; 95 private static final int TEST_UID = 15; 96 private static final long TEST_TIME_OUT_MS = 500; 97 private static final long TEST_REQUEST_ID = 1; 98 99 private static final AudioDeviceInfo TEST_MICROPHONE_INPUT_DEVICE = new 100 AudioDeviceInfoBuilder().setAddressName(MICROPHONE_ADDRESS) 101 .setType(TYPE_BUILTIN_MIC).setIsSource(true).build(); 102 private static final AudioDeviceInfo TEST_TUNER_INPUT_DEVICE = new AudioDeviceInfoBuilder() 103 .setAddressName(FM_TUNER_ADDRESS).setType(TYPE_FM_TUNER).setIsSource(true).build(); 104 private static final AudioDeviceInfo TEST_MEDIA_OUTPUT_DEVICE = new AudioDeviceInfoBuilder() 105 .setAddressName(MEDIA_TEST_DEVICE).build(); 106 private static final AudioDeviceInfo TEST_NAV_OUTPUT_DEVICE = new AudioDeviceInfoBuilder() 107 .setAddressName(NAVIGATION_TEST_DEVICE).build(); 108 109 private static final Executor DIRECT_EXECUTOR = Runnable::run; 110 111 private HandlerThread mHandlerThread; 112 private Handler mHandler; 113 private final RemoteException mRemoteException = new RemoteException(); 114 115 @Mock 116 private ICarBase mCar; 117 @Mock 118 private IBinder mBinderMock; 119 @Mock 120 private ICarAudio mServiceMock; 121 @Mock 122 private AudioManager mAudioManagerMock; 123 @Mock 124 private Context mContextMock; 125 @Mock 126 private CarVolumeGroupInfo mCarVolumeGroupInfoMock1; 127 @Mock 128 private CarVolumeGroupInfo mCarVolumeGroupInfoMock2; 129 @Mock 130 private AudioAttributes mAudioAttributesMock1; 131 @Mock 132 private AudioAttributes mAudioAttributesMock2; 133 @Mock 134 private CarAudioManager.CarVolumeCallback mVolumeCallbackMock1; 135 @Mock 136 private CarAudioManager.CarVolumeCallback mVolumeCallbackMock2; 137 @Mock 138 private CarAudioZoneConfigInfo mZoneConfigInfoMock1; 139 @Mock 140 private CarAudioZoneConfigInfo mZoneConfigInfoMock2; 141 @Mock 142 private OccupantZoneInfo mOccupantZoneInfoMock; 143 @Mock 144 private SwitchAudioZoneConfigCallback mSwitchCallbackMock; 145 @Mock 146 private CarVolumeGroupEventCallback mVolumeGroupEventCallbackMock1; 147 @Mock 148 private CarVolumeGroupEventCallback mVolumeGroupEventCallbackMock2; 149 @Mock 150 private PrimaryZoneMediaAudioRequestCallback mPrimaryZoneMediaAudioRequestCallbackMock; 151 @Mock 152 private MediaAudioRequestStatusCallback mMediaAudioRequestStatusCallbackMock; 153 @Mock 154 private AudioZonesMirrorStatusCallback mAudioZonesMirrorStatusCallback; 155 156 private CarAudioManager mCarAudioManager; 157 private TestAudioZoneConfigurationsChangeCallback mTestConfigCallback; 158 159 @Before setUp()160 public void setUp() throws Exception { 161 mHandlerThread = new HandlerThread(Car_AUDIO_MANAGER_TEST_THREAD_NAME); 162 mHandlerThread.start(); 163 mHandler = new Handler(mHandlerThread.getLooper()); 164 165 when(mBinderMock.queryLocalInterface(anyString())).thenReturn(mServiceMock); 166 when(mCar.getContext()).thenReturn(mContextMock); 167 when(mCar.getEventHandler()).thenReturn(mHandler); 168 when(mContextMock.getSystemService(AudioManager.class)).thenReturn(mAudioManagerMock); 169 mCarAudioManager = new CarAudioManager(mCar, mBinderMock); 170 doAnswer(invocation -> invocation.getArgument(1)).when(mCar) 171 .handleRemoteExceptionFromCarService(any(RemoteException.class), any()); 172 mTestConfigCallback = new TestAudioZoneConfigurationsChangeCallback(); 173 when(mServiceMock.registerAudioZoneConfigsChangeCallback(any())).thenReturn(true); 174 } 175 176 @After tearDown()177 public void tearDown() throws Exception { 178 mHandlerThread.quitSafely(); 179 mHandlerThread.join(); 180 } 181 182 @Test isAudioFeatureEnabled()183 public void isAudioFeatureEnabled() throws Exception { 184 when(mServiceMock.isAudioFeatureEnabled(AUDIO_FEATURE_DYNAMIC_ROUTING)).thenReturn(true); 185 186 expectWithMessage("Dynamic audio routing enabled") 187 .that(mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_DYNAMIC_ROUTING)) 188 .isTrue(); 189 } 190 191 @Test isAudioFeatureEnabled_withServiceRemoteException_returnsFalse()192 public void isAudioFeatureEnabled_withServiceRemoteException_returnsFalse() throws Exception { 193 doThrow(mRemoteException).when(mServiceMock).isAudioFeatureEnabled( 194 AUDIO_FEATURE_DYNAMIC_ROUTING); 195 196 expectWithMessage("Dynamic audio routing disabled when service throws remote exception") 197 .that(mCarAudioManager.isAudioFeatureEnabled(AUDIO_FEATURE_DYNAMIC_ROUTING)) 198 .isFalse(); 199 } 200 201 @Test setGroupVolume_withoutZoneId()202 public void setGroupVolume_withoutZoneId() throws Exception { 203 mCarAudioManager.setGroupVolume(TEST_VOLUME_GROUP_ID, TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 204 205 verify(mServiceMock).setGroupVolume(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID, 206 TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 207 } 208 209 @Test setGroupVolume_withZoneId()210 public void setGroupVolume_withZoneId() throws Exception { 211 mCarAudioManager.setGroupVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 212 TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 213 214 verify(mServiceMock).setGroupVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 215 TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 216 } 217 218 @Test setGroupVolume_withServiceRemoteException()219 public void setGroupVolume_withServiceRemoteException() throws Exception { 220 doThrow(mRemoteException).when(mServiceMock).setGroupVolume(TEST_REAR_RIGHT_ZONE_ID, 221 TEST_VOLUME_GROUP_ID, TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 222 223 mCarAudioManager.setGroupVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 224 TEST_VOLUME_GROUP_INDEX, TEST_FLAGS); 225 226 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 227 } 228 229 @Test getGroupMaxVolume_withoutZoneId()230 public void getGroupMaxVolume_withoutZoneId() throws Exception { 231 when(mServiceMock.getGroupMaxVolume(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID)) 232 .thenReturn(TEST_GAIN_MAX_VALUE); 233 234 expectWithMessage("Primary zone max volume") 235 .that(mCarAudioManager.getGroupMaxVolume(TEST_VOLUME_GROUP_ID)) 236 .isEqualTo(TEST_GAIN_MAX_VALUE); 237 } 238 239 @Test getGroupMaxVolume_withZoneId()240 public void getGroupMaxVolume_withZoneId() throws Exception { 241 when(mServiceMock.getGroupMaxVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 242 .thenReturn(TEST_GAIN_MAX_VALUE); 243 244 expectWithMessage("Rear right zone max volume").that(mCarAudioManager 245 .getGroupMaxVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 246 .isEqualTo(TEST_GAIN_MAX_VALUE); 247 } 248 249 @Test getGroupMaxVolume_withServiceRemoteException()250 public void getGroupMaxVolume_withServiceRemoteException() throws Exception { 251 doThrow(mRemoteException).when(mServiceMock).getGroupMaxVolume(TEST_REAR_RIGHT_ZONE_ID, 252 TEST_VOLUME_GROUP_ID); 253 254 expectWithMessage("Rear right zone max volume when service throws remote exception") 255 .that(mCarAudioManager.getGroupMaxVolume(TEST_REAR_RIGHT_ZONE_ID, 256 TEST_VOLUME_GROUP_ID)).isEqualTo(0); 257 } 258 259 @Test getGroupMinVolume_withoutZoneId()260 public void getGroupMinVolume_withoutZoneId() throws Exception { 261 when(mServiceMock.getGroupMinVolume(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID)) 262 .thenReturn(TEST_GAIN_MIN_VALUE); 263 264 expectWithMessage("Primary zone min volume") 265 .that(mCarAudioManager.getGroupMinVolume(TEST_VOLUME_GROUP_ID)) 266 .isEqualTo(TEST_GAIN_MIN_VALUE); 267 } 268 269 @Test getGroupMinVolume_withZoneId()270 public void getGroupMinVolume_withZoneId() throws Exception { 271 when(mServiceMock.getGroupMinVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 272 .thenReturn(TEST_GAIN_MIN_VALUE); 273 274 expectWithMessage("Rear right zone min volume").that(mCarAudioManager 275 .getGroupMinVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 276 .isEqualTo(TEST_GAIN_MIN_VALUE); 277 } 278 279 @Test getGroupMinVolume_withServiceRemoteException()280 public void getGroupMinVolume_withServiceRemoteException() throws Exception { 281 doThrow(mRemoteException).when(mServiceMock).getGroupMinVolume(TEST_REAR_RIGHT_ZONE_ID, 282 TEST_VOLUME_GROUP_ID); 283 284 expectWithMessage("Rear right zone min volume when service throws remote exception") 285 .that(mCarAudioManager.getGroupMinVolume(TEST_REAR_RIGHT_ZONE_ID, 286 TEST_VOLUME_GROUP_ID)).isEqualTo(0); 287 } 288 289 @Test getGroupVolume_withoutZoneId()290 public void getGroupVolume_withoutZoneId() throws Exception { 291 when(mServiceMock.getGroupVolume(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID)) 292 .thenReturn(TEST_GAIN_DEFAULT_VALUE); 293 294 expectWithMessage("Primary zone volume") 295 .that(mCarAudioManager.getGroupVolume(TEST_VOLUME_GROUP_ID)) 296 .isEqualTo(TEST_GAIN_DEFAULT_VALUE); 297 } 298 299 @Test getGroupVolume_withZoneId()300 public void getGroupVolume_withZoneId() throws Exception { 301 when(mServiceMock.getGroupVolume(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 302 .thenReturn(TEST_GAIN_DEFAULT_VALUE); 303 304 expectWithMessage("Rear right zone volume").that(mCarAudioManager.getGroupVolume( 305 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)).isEqualTo(TEST_GAIN_DEFAULT_VALUE); 306 } 307 308 @Test getGroupVolume_withServiceRemoteException()309 public void getGroupVolume_withServiceRemoteException() throws Exception { 310 doThrow(mRemoteException).when(mServiceMock).getGroupVolume(TEST_REAR_RIGHT_ZONE_ID, 311 TEST_VOLUME_GROUP_ID); 312 313 expectWithMessage("Rear right zone volume when service throws remote exception") 314 .that(mCarAudioManager.getGroupVolume(TEST_REAR_RIGHT_ZONE_ID, 315 TEST_VOLUME_GROUP_ID)).isEqualTo(0); 316 } 317 318 @Test setFadeTowardFront()319 public void setFadeTowardFront() throws Exception { 320 float value = 0.3f; 321 322 mCarAudioManager.setFadeTowardFront(value); 323 324 verify(mServiceMock).setFadeTowardFront(value); 325 } 326 327 @Test setFadeTowardFront_withServiceRemoteException()328 public void setFadeTowardFront_withServiceRemoteException() throws Exception { 329 float value = 0.3f; 330 doThrow(mRemoteException).when(mServiceMock).setFadeTowardFront(value); 331 332 mCarAudioManager.setFadeTowardFront(value); 333 334 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 335 } 336 337 @Test setBalanceTowardRight()338 public void setBalanceTowardRight() throws Exception { 339 float value = 0.4f; 340 341 mCarAudioManager.setBalanceTowardRight(value); 342 343 verify(mServiceMock).setBalanceTowardRight(value); 344 } 345 346 @Test setBalanceTowardRight_withServiceRemoteException()347 public void setBalanceTowardRight_withServiceRemoteException() throws Exception { 348 float value = 0.4f; 349 doThrow(mRemoteException).when(mServiceMock).setBalanceTowardRight(value); 350 351 mCarAudioManager.setBalanceTowardRight(value); 352 353 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 354 } 355 356 @Test getVolumeGroupCount_withoutZoneId()357 public void getVolumeGroupCount_withoutZoneId() throws Exception { 358 when(mServiceMock.getVolumeGroupCount(PRIMARY_AUDIO_ZONE)) 359 .thenReturn(TEST_VOLUME_GROUP_COUNT); 360 361 expectWithMessage("Primary zone volume group count") 362 .that(mCarAudioManager.getVolumeGroupCount()).isEqualTo(TEST_VOLUME_GROUP_COUNT); 363 } 364 365 @Test getVolumeGroupCount_withZoneId()366 public void getVolumeGroupCount_withZoneId() throws Exception { 367 when(mServiceMock.getVolumeGroupCount(TEST_REAR_RIGHT_ZONE_ID)) 368 .thenReturn(TEST_VOLUME_GROUP_COUNT); 369 370 expectWithMessage("Rear right zone volume group count") 371 .that(mCarAudioManager.getVolumeGroupCount(TEST_REAR_RIGHT_ZONE_ID)) 372 .isEqualTo(TEST_VOLUME_GROUP_COUNT); 373 } 374 375 @Test getVolumeGroupCount_withServiceRemoteException()376 public void getVolumeGroupCount_withServiceRemoteException() throws Exception { 377 doThrow(mRemoteException).when(mServiceMock).getVolumeGroupCount( 378 TEST_REAR_RIGHT_ZONE_ID); 379 380 expectWithMessage("Rear right zone volume group count when service throws remote exception") 381 .that(mCarAudioManager.getVolumeGroupCount(TEST_REAR_RIGHT_ZONE_ID)).isEqualTo(0); 382 } 383 384 @Test getVolumeGroupIdForUsage_withoutZoneId()385 public void getVolumeGroupIdForUsage_withoutZoneId() throws Exception { 386 when(mServiceMock.getVolumeGroupIdForUsage(PRIMARY_AUDIO_ZONE, TEST_USAGE)) 387 .thenReturn(TEST_VOLUME_GROUP_ID); 388 389 expectWithMessage("Volume group id for media usage in primary zone") 390 .that(mCarAudioManager.getVolumeGroupIdForUsage(TEST_USAGE)) 391 .isEqualTo(TEST_VOLUME_GROUP_ID); 392 } 393 394 @Test getVolumeGroupIdForUsage_withZoneId()395 public void getVolumeGroupIdForUsage_withZoneId() throws Exception { 396 when(mServiceMock.getVolumeGroupIdForUsage(TEST_REAR_RIGHT_ZONE_ID, TEST_USAGE)) 397 .thenReturn(TEST_VOLUME_GROUP_ID); 398 399 expectWithMessage("Volume group id for media usage in rear right zone") 400 .that(mCarAudioManager.getVolumeGroupIdForUsage(TEST_REAR_RIGHT_ZONE_ID, 401 TEST_USAGE)).isEqualTo(TEST_VOLUME_GROUP_ID); 402 } 403 404 @Test getVolumeGroupIdForUsage_withServiceRemoteException()405 public void getVolumeGroupIdForUsage_withServiceRemoteException() throws Exception { 406 doThrow(mRemoteException).when(mServiceMock).getVolumeGroupIdForUsage( 407 TEST_REAR_RIGHT_ZONE_ID, TEST_USAGE); 408 409 expectWithMessage("Volume group id for media usage in rear right zone when service " 410 + "throws remote exception").that(mCarAudioManager.getVolumeGroupIdForUsage( 411 TEST_REAR_RIGHT_ZONE_ID, TEST_USAGE)).isEqualTo(0); 412 } 413 414 @Test getUsagesForVolumeGroupId_withoutZoneId()415 public void getUsagesForVolumeGroupId_withoutZoneId() throws Exception { 416 int[] volumeGroupUsages = new int[]{USAGE_MEDIA, USAGE_GAME}; 417 when(mServiceMock.getUsagesForVolumeGroupId(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID)) 418 .thenReturn(volumeGroupUsages); 419 420 expectWithMessage("Group %s usages in primary zone", TEST_VOLUME_GROUP_ID) 421 .that(mCarAudioManager.getUsagesForVolumeGroupId(TEST_VOLUME_GROUP_ID)) 422 .isEqualTo(volumeGroupUsages); 423 } 424 425 @Test getUsagesForVolumeGroupId_withZoneId()426 public void getUsagesForVolumeGroupId_withZoneId() throws Exception { 427 int[] volumeGroupUsages = new int[]{USAGE_MEDIA, USAGE_GAME}; 428 when(mServiceMock.getUsagesForVolumeGroupId(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 429 .thenReturn(volumeGroupUsages); 430 431 expectWithMessage("Group %s usages in rear right zone", TEST_VOLUME_GROUP_ID) 432 .that(mCarAudioManager.getUsagesForVolumeGroupId(TEST_REAR_RIGHT_ZONE_ID, 433 TEST_VOLUME_GROUP_ID)).isEqualTo(volumeGroupUsages); 434 } 435 436 @Test getUsagesForVolumeGroupId_withServiceRemoteException_returnsEmptyList()437 public void getUsagesForVolumeGroupId_withServiceRemoteException_returnsEmptyList() 438 throws Exception { 439 doThrow(mRemoteException).when(mServiceMock).getUsagesForVolumeGroupId( 440 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID); 441 442 expectWithMessage("Group %s usages in rear right zone when service throws remote exception", 443 TEST_VOLUME_GROUP_ID).that(mCarAudioManager.getUsagesForVolumeGroupId( 444 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)).asList().isEmpty(); 445 } 446 447 @Test getVolumeGroupInfo()448 public void getVolumeGroupInfo() throws Exception { 449 when(mServiceMock.getVolumeGroupInfo(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 450 .thenReturn(mCarVolumeGroupInfoMock1); 451 452 expectWithMessage("Volume group info with id %s in rear right zone") 453 .that(mCarAudioManager.getVolumeGroupInfo(TEST_REAR_RIGHT_ZONE_ID, 454 TEST_VOLUME_GROUP_ID)).isEqualTo(mCarVolumeGroupInfoMock1); 455 } 456 457 @Test getVolumeGroupInfo_withServiceRemoteException_returnsNull()458 public void getVolumeGroupInfo_withServiceRemoteException_returnsNull() throws Exception { 459 doThrow(mRemoteException).when(mServiceMock).getVolumeGroupInfo( 460 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID); 461 462 expectWithMessage("Volume group info with id %s in rear right zone when service throws " 463 + "remote exception").that(mCarAudioManager.getVolumeGroupInfo( 464 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)).isNull(); 465 } 466 467 @Test getVolumeGroupInfosForZone()468 public void getVolumeGroupInfosForZone() throws Exception { 469 when(mServiceMock.getVolumeGroupInfosForZone(TEST_REAR_RIGHT_ZONE_ID)) 470 .thenReturn(List.of(mCarVolumeGroupInfoMock1, mCarVolumeGroupInfoMock2)); 471 472 expectWithMessage("Volume group infos in rear right zone") 473 .that(mCarAudioManager.getVolumeGroupInfosForZone(TEST_REAR_RIGHT_ZONE_ID)) 474 .containsExactly(mCarVolumeGroupInfoMock1, mCarVolumeGroupInfoMock2); 475 } 476 477 @Test getVolumeGroupInfosForZone_withServiceRemoteException_returnsEmptyList()478 public void getVolumeGroupInfosForZone_withServiceRemoteException_returnsEmptyList() 479 throws Exception { 480 doThrow(mRemoteException).when(mServiceMock).getVolumeGroupInfosForZone( 481 TEST_REAR_RIGHT_ZONE_ID); 482 483 expectWithMessage("Volume group infos in rear right zone when service throws remote " 484 + "exception").that(mCarAudioManager.getVolumeGroupInfosForZone( 485 TEST_REAR_RIGHT_ZONE_ID)).isEmpty(); 486 } 487 488 @Test getAudioAttributesForVolumeGroup()489 public void getAudioAttributesForVolumeGroup() throws Exception { 490 List<AudioAttributes> attributesList = List.of(mAudioAttributesMock1, 491 mAudioAttributesMock2); 492 when(mServiceMock.getAudioAttributesForVolumeGroup(mCarVolumeGroupInfoMock1)) 493 .thenReturn(attributesList); 494 495 expectWithMessage("Audio attributes for volume group").that(mCarAudioManager 496 .getAudioAttributesForVolumeGroup(mCarVolumeGroupInfoMock1)) 497 .isEqualTo(attributesList); 498 } 499 500 @Test getAudioAttributesForVolumeGroup_withServiceRemoteException_returnsEmptyList()501 public void getAudioAttributesForVolumeGroup_withServiceRemoteException_returnsEmptyList() 502 throws Exception { 503 doThrow(mRemoteException).when(mServiceMock).getAudioAttributesForVolumeGroup( 504 mCarVolumeGroupInfoMock1); 505 506 expectWithMessage("Audio attributes for volume group when service throws remote exception") 507 .that(mCarAudioManager.getAudioAttributesForVolumeGroup(mCarVolumeGroupInfoMock1)) 508 .isEmpty(); 509 } 510 511 @Test isPlaybackOnVolumeGroupActive()512 public void isPlaybackOnVolumeGroupActive() throws Exception { 513 when(mServiceMock.isPlaybackOnVolumeGroupActive(TEST_REAR_RIGHT_ZONE_ID, 514 TEST_VOLUME_GROUP_ID)).thenReturn(true); 515 516 expectWithMessage("Enabled playback on volume group %s in rear right zone", 517 TEST_VOLUME_GROUP_ID).that(mCarAudioManager.isPlaybackOnVolumeGroupActive( 518 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)).isTrue(); 519 } 520 521 @Test isPlaybackOnVolumeGroupActive_withServiceRemoteException_returnsFalse()522 public void isPlaybackOnVolumeGroupActive_withServiceRemoteException_returnsFalse() 523 throws Exception { 524 doThrow(mRemoteException).when(mServiceMock).isPlaybackOnVolumeGroupActive( 525 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID); 526 527 expectWithMessage("Enabled playback on volume group %s in rear right zone when service " 528 + "throws remote exception", TEST_VOLUME_GROUP_ID).that(mCarAudioManager 529 .isPlaybackOnVolumeGroupActive(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 530 .isFalse(); 531 } 532 533 @Test getAudioZoneIds()534 public void getAudioZoneIds() throws Exception { 535 int[] expectedZoneIds = new int[]{PRIMARY_AUDIO_ZONE, TEST_REAR_LEFT_ZONE_ID, 536 TEST_REAR_RIGHT_ZONE_ID, TEST_FRONT_ZONE_ID}; 537 when(mServiceMock.getAudioZoneIds()).thenReturn(expectedZoneIds); 538 539 expectWithMessage("Zone ids").that(mCarAudioManager.getAudioZoneIds()) 540 .containsExactly(PRIMARY_AUDIO_ZONE, TEST_REAR_LEFT_ZONE_ID, 541 TEST_REAR_RIGHT_ZONE_ID, TEST_FRONT_ZONE_ID).inOrder(); 542 } 543 544 @Test getAudioZoneIds_withServiceRemoteException_returnsEmptyList()545 public void getAudioZoneIds_withServiceRemoteException_returnsEmptyList() throws Exception { 546 doThrow(mRemoteException).when(mServiceMock).getAudioZoneIds(); 547 548 expectWithMessage("Zone ids when service throws remote exception") 549 .that(mCarAudioManager.getAudioZoneIds()).isEmpty(); 550 } 551 552 @Test getZoneIdForUid()553 public void getZoneIdForUid() throws Exception { 554 when(mServiceMock.getZoneIdForUid(TEST_UID)).thenReturn(TEST_REAR_LEFT_ZONE_ID); 555 556 expectWithMessage("Zone id for uid %s", TEST_UID).that(mCarAudioManager 557 .getZoneIdForUid(TEST_UID)).isEqualTo(TEST_REAR_LEFT_ZONE_ID); 558 } 559 560 @Test getZoneIdForUid_withServiceRemoteException()561 public void getZoneIdForUid_withServiceRemoteException() throws Exception { 562 doThrow(mRemoteException).when(mServiceMock).getZoneIdForUid(TEST_UID); 563 564 expectWithMessage("Zone id for uid %s when service throws remote exception", TEST_UID) 565 .that(mCarAudioManager.getZoneIdForUid(TEST_UID)).isEqualTo(0); 566 } 567 568 @Test setZoneIdForUid()569 public void setZoneIdForUid() throws Exception { 570 when(mServiceMock.setZoneIdForUid(TEST_REAR_RIGHT_ZONE_ID, TEST_UID)).thenReturn(true); 571 572 expectWithMessage("Status for setting uid %s to rear right zone", TEST_UID) 573 .that(mCarAudioManager.setZoneIdForUid(TEST_REAR_RIGHT_ZONE_ID, TEST_UID)).isTrue(); 574 } 575 576 @Test setZoneIdForUid_withServiceRemoteException_returnsFalse()577 public void setZoneIdForUid_withServiceRemoteException_returnsFalse() throws Exception { 578 doThrow(mRemoteException).when(mServiceMock).setZoneIdForUid(TEST_REAR_RIGHT_ZONE_ID, 579 TEST_UID); 580 581 expectWithMessage("Status for setting uid %s to rear right zone when service throws " 582 + "remote exception").that(mCarAudioManager.setZoneIdForUid(TEST_REAR_RIGHT_ZONE_ID, 583 TEST_UID)).isFalse(); 584 } 585 586 @Test clearZoneIdForUid()587 public void clearZoneIdForUid() throws Exception { 588 when(mServiceMock.clearZoneIdForUid(TEST_UID)).thenReturn(true); 589 590 expectWithMessage("Status for clearing zone id for uid %s", TEST_UID) 591 .that(mCarAudioManager.clearZoneIdForUid(TEST_UID)).isTrue(); 592 } 593 594 @Test clearZoneIdForUid_withServiceRemoteException_returnsFalse()595 public void clearZoneIdForUid_withServiceRemoteException_returnsFalse() throws Exception { 596 doThrow(mRemoteException).when(mServiceMock).clearZoneIdForUid(TEST_UID); 597 598 expectWithMessage("Status for clearing zone id for uid when service throws remote " 599 + "exception").that(mCarAudioManager.clearZoneIdForUid(TEST_UID)).isFalse(); 600 } 601 602 @Test registerCarVolumeGroupEventCallback()603 public void registerCarVolumeGroupEventCallback() throws Exception { 604 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 605 606 expectWithMessage("Status for registering car volume group event callback") 607 .that(mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 608 mVolumeGroupEventCallbackMock1)).isTrue(); 609 } 610 611 @Test registerCarVolumeGroupEventCallback_withMultipleCallbacks()612 public void registerCarVolumeGroupEventCallback_withMultipleCallbacks() throws Exception { 613 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 614 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 615 mVolumeGroupEventCallbackMock1); 616 verify(mServiceMock).registerCarVolumeEventCallback(any()); 617 clearInvocations(mServiceMock); 618 619 expectWithMessage("Status for registering second car volume group event callback") 620 .that(mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 621 mVolumeGroupEventCallbackMock2)).isTrue(); 622 verify(mServiceMock, never()).registerCarVolumeEventCallback(any()); 623 } 624 625 @Test registerCarVolumeGroupEventCallback_withServiceReturnsFalse_returnsFalse()626 public void registerCarVolumeGroupEventCallback_withServiceReturnsFalse_returnsFalse() 627 throws Exception { 628 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(false); 629 630 expectWithMessage("Failure for registering car volume group event callback") 631 .that(mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 632 mVolumeGroupEventCallbackMock1)).isFalse(); 633 } 634 635 @Test registerCarVolumeGroupEventCallback_withSameCallbackforMultipleTimes_returnsFalse()636 public void registerCarVolumeGroupEventCallback_withSameCallbackforMultipleTimes_returnsFalse() 637 throws Exception { 638 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 639 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 640 mVolumeGroupEventCallbackMock1); 641 642 expectWithMessage("Failure for registering car volume group event callback " 643 + "for multiple times").that(mCarAudioManager.registerCarVolumeGroupEventCallback( 644 DIRECT_EXECUTOR, mVolumeGroupEventCallbackMock1)).isFalse(); 645 } 646 647 @Test registerCarVolumeGroupEventCallback_withNullExecutor_fails()648 public void registerCarVolumeGroupEventCallback_withNullExecutor_fails() { 649 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 650 mCarAudioManager.registerCarVolumeGroupEventCallback(/* executor= */ null, 651 mVolumeGroupEventCallbackMock1)); 652 653 expectWithMessage("Exception for registering car volume group event callback with " 654 + "null executor").that(thrown).hasMessageThat() 655 .contains("Executor can not be null"); 656 } 657 658 @Test registerCarVolumeGroupEventCallback_withNullCallback_fails()659 public void registerCarVolumeGroupEventCallback_withNullCallback_fails() { 660 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 661 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 662 /* callback= */ null)); 663 664 expectWithMessage("Exception for registering null car volume group event callback") 665 .that(thrown).hasMessageThat() 666 .contains("Car volume event callback can not be null"); 667 } 668 669 @Test registerCarVolumeGroupEventCallback_withServiceRemoteException_returnsFalse()670 public void registerCarVolumeGroupEventCallback_withServiceRemoteException_returnsFalse() 671 throws Exception { 672 doThrow(mRemoteException).when(mServiceMock).registerCarVolumeEventCallback(any()); 673 674 expectWithMessage("Failure for registering car volume group event callback when service " 675 + "throws remote exception").that(mCarAudioManager 676 .registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 677 mVolumeGroupEventCallbackMock1)).isFalse(); 678 } 679 680 @Test unregisterCarVolumeGroupEventCallback_withPartOfCallbacks()681 public void unregisterCarVolumeGroupEventCallback_withPartOfCallbacks() throws Exception { 682 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 683 ICarVolumeEventCallback serviceCallback = getCarVolumeEventCallbackImpl( 684 mVolumeGroupEventCallbackMock1); 685 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 686 mVolumeGroupEventCallbackMock2); 687 688 mCarAudioManager.unregisterCarVolumeGroupEventCallback(mVolumeGroupEventCallbackMock1); 689 690 verify(mServiceMock, never()).unregisterCarVolumeEventCallback(serviceCallback); 691 } 692 693 @Test unregisterCarVolumeGroupEventCallback_withAllCallbacks()694 public void unregisterCarVolumeGroupEventCallback_withAllCallbacks() throws Exception { 695 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 696 ICarVolumeEventCallback serviceCallback = getCarVolumeEventCallbackImpl( 697 mVolumeGroupEventCallbackMock1); 698 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 699 mVolumeGroupEventCallbackMock2); 700 mCarAudioManager.unregisterCarVolumeGroupEventCallback(mVolumeGroupEventCallbackMock1); 701 verify(mServiceMock, never()).unregisterCarVolumeEventCallback(serviceCallback); 702 703 mCarAudioManager.unregisterCarVolumeGroupEventCallback(mVolumeGroupEventCallbackMock2); 704 705 verify(mServiceMock).unregisterCarVolumeEventCallback(serviceCallback); 706 } 707 708 @Test unregisterCarVolumeGroupEventCallback_withNullCallback_fails()709 public void unregisterCarVolumeGroupEventCallback_withNullCallback_fails() { 710 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 711 mCarAudioManager.unregisterCarVolumeGroupEventCallback(/* callback= */ null)); 712 713 expectWithMessage("Exception for unregistering null car volume group event callback") 714 .that(thrown).hasMessageThat() 715 .contains("Car volume event callback can not be null"); 716 } 717 718 @Test unregisterCarVolumeGroupEventCallback_withServiceRemoteException()719 public void unregisterCarVolumeGroupEventCallback_withServiceRemoteException() 720 throws Exception { 721 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 722 ICarVolumeEventCallback serviceCallback = getCarVolumeEventCallbackImpl( 723 mVolumeGroupEventCallbackMock1); 724 doThrow(mRemoteException).when(mServiceMock).unregisterCarVolumeEventCallback( 725 serviceCallback); 726 727 mCarAudioManager.unregisterCarVolumeGroupEventCallback(mVolumeGroupEventCallbackMock1); 728 } 729 730 @Test onVolumeGroupEvent_forICarVolumeEventCallback()731 public void onVolumeGroupEvent_forICarVolumeEventCallback() throws Exception { 732 List<CarVolumeGroupEvent> groupEvents = List.of(new CarVolumeGroupEvent.Builder( 733 List.of(mCarVolumeGroupInfoMock1), CarVolumeGroupEvent.EVENT_TYPE_MUTE_CHANGED) 734 .build(), new CarVolumeGroupEvent.Builder( 735 List.of(mCarVolumeGroupInfoMock2), 736 CarVolumeGroupEvent.EVENT_TYPE_VOLUME_BLOCKED_CHANGED).build()); 737 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 738 ICarVolumeEventCallback serviceCallback = getCarVolumeEventCallbackImpl( 739 mVolumeGroupEventCallbackMock1); 740 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, 741 mVolumeGroupEventCallbackMock2); 742 743 serviceCallback.onVolumeGroupEvent(groupEvents); 744 745 verify(mVolumeGroupEventCallbackMock1, timeout(TEST_TIME_OUT_MS)).onVolumeGroupEvent( 746 groupEvents); 747 verify(mVolumeGroupEventCallbackMock2, timeout(TEST_TIME_OUT_MS)).onVolumeGroupEvent( 748 groupEvents); 749 } 750 751 @Test onMasterMuteChanged_forICarVolumeEventCallback()752 public void onMasterMuteChanged_forICarVolumeEventCallback() throws Exception { 753 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 754 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 755 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock2); 756 ICarVolumeEventCallback serviceCallback = getCarVolumeEventCallbackImpl( 757 mVolumeGroupEventCallbackMock1); 758 759 serviceCallback.onMasterMuteChanged(TEST_REAR_RIGHT_ZONE_ID, TEST_FLAGS); 760 761 verify(mVolumeCallbackMock1, timeout(TEST_TIME_OUT_MS)).onMasterMuteChanged( 762 TEST_REAR_RIGHT_ZONE_ID, TEST_FLAGS); 763 verify(mVolumeCallbackMock2, timeout(TEST_TIME_OUT_MS)).onMasterMuteChanged( 764 TEST_REAR_RIGHT_ZONE_ID, TEST_FLAGS); 765 } 766 767 @Test isVolumeGroupMuted()768 public void isVolumeGroupMuted() throws Exception { 769 when(mServiceMock.isVolumeGroupMuted(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)) 770 .thenReturn(true); 771 772 expectWithMessage("Muted volume group").that(mCarAudioManager.isVolumeGroupMuted( 773 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID)).isTrue(); 774 } 775 776 @Test isVolumeGroupMuted_withServiceRemoteException_returnsFalse()777 public void isVolumeGroupMuted_withServiceRemoteException_returnsFalse() throws Exception { 778 doThrow(mRemoteException).when(mServiceMock).isVolumeGroupMuted( 779 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID); 780 781 expectWithMessage("Muted volume group when service throws remote exception") 782 .that(mCarAudioManager.isVolumeGroupMuted(TEST_REAR_RIGHT_ZONE_ID, 783 TEST_VOLUME_GROUP_ID)).isFalse(); 784 } 785 786 @Test setVolumeGroupMute()787 public void setVolumeGroupMute() throws Exception { 788 mCarAudioManager.setVolumeGroupMute(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 789 /* mute= */ true, TEST_FLAGS); 790 791 verify(mServiceMock).setVolumeGroupMute(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 792 /* mute= */ true, TEST_FLAGS); 793 } 794 795 @Test setVolumeGroupMute_withServiceRemoteException()796 public void setVolumeGroupMute_withServiceRemoteException() throws Exception { 797 doThrow(mRemoteException).when(mServiceMock).setVolumeGroupMute( 798 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, /* mute= */ true, TEST_FLAGS); 799 800 mCarAudioManager.setVolumeGroupMute(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, 801 /* mute= */ true, TEST_FLAGS); 802 803 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 804 } 805 806 @Test registerCarVolumeCallback()807 public void registerCarVolumeCallback() throws Exception { 808 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 809 810 verify(mServiceMock).registerVolumeCallback(any(IBinder.class)); 811 } 812 813 @Test registerCarVolumeCallback_withMultipleCallbacks()814 public void registerCarVolumeCallback_withMultipleCallbacks() throws Exception { 815 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 816 verify(mServiceMock).registerVolumeCallback(any(IBinder.class)); 817 clearInvocations(mServiceMock); 818 819 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock2); 820 821 verify(mServiceMock, never()).registerVolumeCallback(any(IBinder.class)); 822 } 823 824 @Test unregisterCarVolumeCallback_withPartOfCallbacks()825 public void unregisterCarVolumeCallback_withPartOfCallbacks() throws Exception { 826 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 827 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock2); 828 829 mCarAudioManager.unregisterCarVolumeCallback(mVolumeCallbackMock1); 830 831 verify(mServiceMock, never()).unregisterVolumeCallback(any(IBinder.class)); 832 } 833 834 @Test unregisterCarVolumeCallback_withAllCallbacks()835 public void unregisterCarVolumeCallback_withAllCallbacks() throws Exception { 836 ArgumentCaptor<IBinder> captor = ArgumentCaptor.forClass(IBinder.class); 837 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 838 verify(mServiceMock).registerVolumeCallback(captor.capture()); 839 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock2); 840 841 mCarAudioManager.unregisterCarVolumeCallback(mVolumeCallbackMock1); 842 mCarAudioManager.unregisterCarVolumeCallback(mVolumeCallbackMock2); 843 844 verify(mServiceMock).unregisterVolumeCallback(captor.getValue()); 845 } 846 847 @Test unregisterCarVolumeCallback_withServiceRemoteException()848 public void unregisterCarVolumeCallback_withServiceRemoteException() throws Exception { 849 mCarAudioManager.registerCarVolumeCallback(mVolumeCallbackMock1); 850 verify(mServiceMock).registerVolumeCallback(any()); 851 doThrow(mRemoteException).when(mServiceMock).unregisterVolumeCallback(any()); 852 853 mCarAudioManager.unregisterCarVolumeCallback(mVolumeCallbackMock1); 854 855 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 856 } 857 858 @Test onCarDisconnected()859 public void onCarDisconnected() throws Exception { 860 ICarVolumeCallback serviceVolCallback = getCarVolumeCallbackImpl(mVolumeCallbackMock1); 861 ICarVolumeEventCallback serviceVolEventCallback = getCarVolumeEventCallbackImpl( 862 mVolumeGroupEventCallbackMock1); 863 864 mCarAudioManager.onCarDisconnected(); 865 866 verify(mServiceMock).unregisterVolumeCallback(serviceVolCallback.asBinder()); 867 verify(mServiceMock).unregisterCarVolumeEventCallback(serviceVolEventCallback); 868 } 869 870 @Test onGroupMuteChanged_forCarVolumeCallback()871 public void onGroupMuteChanged_forCarVolumeCallback() throws Exception { 872 ICarVolumeCallback callbackImpl = getCarVolumeCallbackImpl(mVolumeCallbackMock1); 873 874 callbackImpl.onGroupMuteChanged(TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, TEST_FLAGS); 875 876 verify(mVolumeCallbackMock1, timeout(TEST_TIME_OUT_MS)).onGroupMuteChanged( 877 TEST_REAR_RIGHT_ZONE_ID, TEST_VOLUME_GROUP_ID, TEST_FLAGS); 878 } 879 880 @Test onGroupVolumeChanged_forCarVolumeCallback()881 public void onGroupVolumeChanged_forCarVolumeCallback() throws Exception { 882 ICarVolumeCallback callbackImpl = getCarVolumeCallbackImpl(mVolumeCallbackMock1); 883 884 callbackImpl.onGroupVolumeChanged(PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID, TEST_FLAGS); 885 886 verify(mVolumeCallbackMock1, timeout(TEST_TIME_OUT_MS)).onGroupVolumeChanged( 887 PRIMARY_AUDIO_ZONE, TEST_VOLUME_GROUP_ID, TEST_FLAGS); 888 } 889 890 @Test onMasterMuteChanged_forCarVolumeCallback()891 public void onMasterMuteChanged_forCarVolumeCallback() throws Exception { 892 ICarVolumeCallback callbackImpl = getCarVolumeCallbackImpl(mVolumeCallbackMock1); 893 894 callbackImpl.onMasterMuteChanged(TEST_REAR_LEFT_ZONE_ID, TEST_FLAGS); 895 896 verify(mVolumeCallbackMock1, timeout(TEST_TIME_OUT_MS)).onMasterMuteChanged( 897 TEST_REAR_LEFT_ZONE_ID, TEST_FLAGS); 898 } 899 900 @Test getAudioZoneConfigInfos()901 public void getAudioZoneConfigInfos() throws Exception { 902 List<CarAudioZoneConfigInfo> zoneConfigInfos = List.of(mZoneConfigInfoMock1, 903 mZoneConfigInfoMock2); 904 when(mServiceMock.getAudioZoneConfigInfos(TEST_REAR_RIGHT_ZONE_ID)) 905 .thenReturn(zoneConfigInfos); 906 907 expectWithMessage("All configuration infos for rear right zone") 908 .that(mCarAudioManager.getAudioZoneConfigInfos(TEST_REAR_RIGHT_ZONE_ID)) 909 .isEqualTo(zoneConfigInfos); 910 } 911 912 @Test getAudioZoneConfigInfos_withServiceRemoteException_returnsEmptyList()913 public void getAudioZoneConfigInfos_withServiceRemoteException_returnsEmptyList() 914 throws Exception { 915 doThrow(mRemoteException).when(mServiceMock).getAudioZoneConfigInfos( 916 TEST_REAR_RIGHT_ZONE_ID); 917 918 expectWithMessage("All configuration infos for rear right zone when service throws" 919 + " remote exception").that(mCarAudioManager.getAudioZoneConfigInfos( 920 TEST_REAR_RIGHT_ZONE_ID)).isEmpty(); 921 } 922 923 @Test getCurrentAudioZoneConfigInfo()924 public void getCurrentAudioZoneConfigInfo() throws Exception { 925 when(mServiceMock.getCurrentAudioZoneConfigInfo(TEST_REAR_RIGHT_ZONE_ID)) 926 .thenReturn(mZoneConfigInfoMock1); 927 928 expectWithMessage("Current configuration info for rear right zone") 929 .that(mCarAudioManager.getCurrentAudioZoneConfigInfo(TEST_REAR_RIGHT_ZONE_ID)) 930 .isEqualTo(mZoneConfigInfoMock1); 931 } 932 933 @Test getCurrentAudioZoneConfigInfo_whenServiceThrowsRemoteException_returnsNull()934 public void getCurrentAudioZoneConfigInfo_whenServiceThrowsRemoteException_returnsNull() 935 throws Exception { 936 doThrow(mRemoteException).when(mServiceMock).getCurrentAudioZoneConfigInfo( 937 TEST_REAR_RIGHT_ZONE_ID); 938 939 expectWithMessage("Current configuration info for rear right zone when service throws " 940 + "remote exception").that(mCarAudioManager.getCurrentAudioZoneConfigInfo( 941 TEST_REAR_RIGHT_ZONE_ID)).isNull(); 942 } 943 944 @Test switchAudioZoneToConfig()945 public void switchAudioZoneToConfig() throws Exception { 946 doAnswer(invocation -> { 947 CarAudioZoneConfigInfo configInfoToSwitch = invocation.getArgument(0); 948 ISwitchAudioZoneConfigCallback serviceCallback = invocation.getArgument(1); 949 serviceCallback.onAudioZoneConfigSwitched(configInfoToSwitch, /* isSuccessful= */ true); 950 return null; 951 }).when(mServiceMock).switchZoneToConfig(any(CarAudioZoneConfigInfo.class), 952 any(ISwitchAudioZoneConfigCallback.class)); 953 954 mCarAudioManager.switchAudioZoneToConfig(mZoneConfigInfoMock1, DIRECT_EXECUTOR, 955 mSwitchCallbackMock); 956 957 verify(mSwitchCallbackMock).onAudioZoneConfigSwitched(mZoneConfigInfoMock1, 958 /* isSuccessful= */ true); 959 } 960 961 @Test switchAudioZoneToConfig_withNullConfig_fails()962 public void switchAudioZoneToConfig_withNullConfig_fails() { 963 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 964 mCarAudioManager.switchAudioZoneToConfig(/* zoneConfig= */ null, DIRECT_EXECUTOR, 965 mSwitchCallbackMock)); 966 967 expectWithMessage("Exception for switching zone configuration with null executor") 968 .that(thrown).hasMessageThat() 969 .contains("Audio zone configuration can not be null"); 970 } 971 972 @Test switchAudioZoneToConfig_withNullExecutor_fails()973 public void switchAudioZoneToConfig_withNullExecutor_fails() { 974 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 975 mCarAudioManager.switchAudioZoneToConfig(mZoneConfigInfoMock1, /* executor= */ null, 976 mSwitchCallbackMock)); 977 978 expectWithMessage("Exception for switching zone configuration with null executor") 979 .that(thrown).hasMessageThat() 980 .contains("Executor can not be null"); 981 } 982 983 @Test switchAudioZoneToConfig_withNullCallback_fails()984 public void switchAudioZoneToConfig_withNullCallback_fails() { 985 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 986 mCarAudioManager.switchAudioZoneToConfig(mZoneConfigInfoMock1, DIRECT_EXECUTOR, 987 /* callback= */ null)); 988 989 expectWithMessage("Exception for switching zone configuration with null callback") 990 .that(thrown).hasMessageThat() 991 .contains("Switching audio zone configuration result callback can not be null"); 992 } 993 994 @Test switchAudioZoneToConfig_whenServiceThrowsRemoteException()995 public void switchAudioZoneToConfig_whenServiceThrowsRemoteException() throws Exception { 996 doThrow(mRemoteException).when(mServiceMock).switchZoneToConfig(any( 997 CarAudioZoneConfigInfo.class), any(ISwitchAudioZoneConfigCallback.class)); 998 999 mCarAudioManager.switchAudioZoneToConfig(mZoneConfigInfoMock1, DIRECT_EXECUTOR, 1000 mSwitchCallbackMock); 1001 1002 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1003 } 1004 1005 @Test setAudioZoneConfigsChangeCallback_withNullExecutor_fails()1006 public void setAudioZoneConfigsChangeCallback_withNullExecutor_fails() { 1007 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1008 mCarAudioManager.setAudioZoneConfigsChangeCallback(/* executor= */ null, 1009 mTestConfigCallback)); 1010 1011 expectWithMessage("Null audio zone config callback executor exception").that(thrown) 1012 .hasMessageThat().contains("Executor"); 1013 } 1014 1015 @Test setAudioZoneConfigsChangeCallback_withNullCallback_fails()1016 public void setAudioZoneConfigsChangeCallback_withNullCallback_fails() { 1017 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1018 mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1019 /* callback= */ null)); 1020 1021 expectWithMessage("Null audio zone config callback exception").that(thrown) 1022 .hasMessageThat().contains("Audio zone configs change callback"); 1023 } 1024 1025 @Test setAudioZoneConfigsChangeCallback()1026 public void setAudioZoneConfigsChangeCallback() throws Exception { 1027 boolean registered = mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1028 mTestConfigCallback); 1029 1030 expectWithMessage("Audio zone configs callback registered status").that(registered) 1031 .isTrue(); 1032 verify(mServiceMock).registerAudioZoneConfigsChangeCallback(any()); 1033 } 1034 1035 @Test setAudioZoneConfigsChangeCallback_multipleTimes_fails()1036 public void setAudioZoneConfigsChangeCallback_multipleTimes_fails() { 1037 mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, mTestConfigCallback); 1038 1039 IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> 1040 mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1041 mTestConfigCallback)); 1042 1043 expectWithMessage("Audio zone configs callback re-registered exception").that(thrown) 1044 .hasMessageThat().contains("already set"); 1045 } 1046 1047 @Test onAudioZoneConfigurationsChanged_onRegisteredCallback()1048 public void onAudioZoneConfigurationsChanged_onRegisteredCallback() throws Exception { 1049 mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1050 mTestConfigCallback); 1051 ArgumentCaptor<IAudioZoneConfigurationsChangeCallback> captor = 1052 ArgumentCaptor.forClass(IAudioZoneConfigurationsChangeCallback.class); 1053 verify(mServiceMock).registerAudioZoneConfigsChangeCallback(captor.capture()); 1054 IAudioZoneConfigurationsChangeCallback remoteCallback = captor.getValue(); 1055 1056 remoteCallback.onAudioZoneConfigurationsChanged( 1057 List.of(mZoneConfigInfoMock1, mZoneConfigInfoMock2), CONFIG_STATUS_CHANGED); 1058 1059 mTestConfigCallback.waitForCallback(); 1060 expectWithMessage("Triggered callback configs").that(mTestConfigCallback.mInfos) 1061 .containsExactly(mZoneConfigInfoMock1, mZoneConfigInfoMock2); 1062 expectWithMessage("Triggered callback status").that(mTestConfigCallback.mStatus) 1063 .isEqualTo(CONFIG_STATUS_CHANGED); 1064 } 1065 1066 @Test clearAudioZoneConfigsCallback()1067 public void clearAudioZoneConfigsCallback() throws Exception { 1068 mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1069 mTestConfigCallback); 1070 1071 mCarAudioManager.clearAudioZoneConfigsCallback(); 1072 1073 verify(mServiceMock).unregisterAudioZoneConfigsChangeCallback(any()); 1074 } 1075 1076 @Test clearAudioZoneConfigsCallback_withNoRegisteredCallback()1077 public void clearAudioZoneConfigsCallback_withNoRegisteredCallback() throws Exception { 1078 mCarAudioManager.clearAudioZoneConfigsCallback(); 1079 1080 verify(mServiceMock, never()).unregisterAudioZoneConfigsChangeCallback(any()); 1081 } 1082 1083 @Test setAudioZoneConfigsChangeCallback_withServiceException_fails()1084 public void setAudioZoneConfigsChangeCallback_withServiceException_fails() throws Exception { 1085 RemoteException remoteException = new RemoteException("Register failed!"); 1086 when(mServiceMock.registerAudioZoneConfigsChangeCallback(any())).thenThrow(remoteException); 1087 1088 boolean registered = mCarAudioManager.setAudioZoneConfigsChangeCallback(DIRECT_EXECUTOR, 1089 mTestConfigCallback); 1090 1091 expectWithMessage("Audio zone configs callback registered status after service exception") 1092 .that(registered).isFalse(); 1093 } 1094 1095 @Test setPrimaryZoneMediaAudioRequestCallback()1096 public void setPrimaryZoneMediaAudioRequestCallback() throws Exception { 1097 when(mServiceMock.registerPrimaryZoneMediaAudioRequestCallback(any())).thenReturn(true); 1098 1099 expectWithMessage("Status for setting primary zone media audio request callback") 1100 .that(mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1101 mPrimaryZoneMediaAudioRequestCallbackMock)).isTrue(); 1102 } 1103 1104 @Test setPrimaryZoneMediaAudioRequestCallback_fails()1105 public void setPrimaryZoneMediaAudioRequestCallback_fails() throws Exception { 1106 when(mServiceMock.registerPrimaryZoneMediaAudioRequestCallback(any())).thenReturn(false); 1107 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1108 mPrimaryZoneMediaAudioRequestCallbackMock); 1109 1110 expectWithMessage("Failure for setting primary zone media audio request callback") 1111 .that(mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1112 mPrimaryZoneMediaAudioRequestCallbackMock)).isFalse(); 1113 } 1114 1115 @Test setPrimaryZoneMediaAudioRequestCallback_withNullExecutor_fails()1116 public void setPrimaryZoneMediaAudioRequestCallback_withNullExecutor_fails() { 1117 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1118 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(/* executor= */ null, 1119 mPrimaryZoneMediaAudioRequestCallbackMock)); 1120 1121 expectWithMessage("Exception for setting primary zone media audio request callback with" 1122 + "null executor").that(thrown).hasMessageThat() 1123 .contains("Executor can not be null"); 1124 } 1125 1126 @Test setPrimaryZoneMediaAudioRequestCallback_withNullCallback_fails()1127 public void setPrimaryZoneMediaAudioRequestCallback_withNullCallback_fails() { 1128 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1129 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1130 /* callback= */ null)); 1131 1132 expectWithMessage("Exception for setting null primary zone media audio request callback") 1133 .that(thrown).hasMessageThat() 1134 .contains("Audio media request callback can not be null"); 1135 } 1136 1137 @Test setPrimaryZoneMediaAudioRequestCallback_forMultipleTimes_fails()1138 public void setPrimaryZoneMediaAudioRequestCallback_forMultipleTimes_fails() throws Exception { 1139 when(mServiceMock.registerPrimaryZoneMediaAudioRequestCallback(any())).thenReturn(true); 1140 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1141 mPrimaryZoneMediaAudioRequestCallbackMock); 1142 1143 IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> 1144 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1145 mock(PrimaryZoneMediaAudioRequestCallback.class))); 1146 1147 expectWithMessage("Exception for setting primary zone media audio request callback" 1148 + " for multiple times").that(thrown).hasMessageThat() 1149 .contains("Primary zone media audio request is already set"); 1150 } 1151 1152 @Test setPrimaryZoneMediaAudioRequestCallback_afterClearingPreviousCallbacks()1153 public void setPrimaryZoneMediaAudioRequestCallback_afterClearingPreviousCallbacks() 1154 throws Exception { 1155 when(mServiceMock.registerPrimaryZoneMediaAudioRequestCallback(any())).thenReturn(true); 1156 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1157 mPrimaryZoneMediaAudioRequestCallbackMock); 1158 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1159 1160 expectWithMessage("Status for setting primary zone media audio request callback" 1161 + " again after clearing previous callbacks").that(mCarAudioManager 1162 .setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1163 mock(PrimaryZoneMediaAudioRequestCallback.class))).isTrue(); 1164 } 1165 1166 @Test setPrimaryZoneMediaAudioRequestCallback_whenServiceThrowsRemoteException()1167 public void setPrimaryZoneMediaAudioRequestCallback_whenServiceThrowsRemoteException() 1168 throws Exception { 1169 doThrow(mRemoteException).when(mServiceMock) 1170 .registerPrimaryZoneMediaAudioRequestCallback(any()); 1171 1172 expectWithMessage("Status for setting primary zone media audio request callback " 1173 + "when service throws remote exception").that(mCarAudioManager 1174 .setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, 1175 mPrimaryZoneMediaAudioRequestCallbackMock)).isFalse(); 1176 } 1177 1178 @Test clearPrimaryZoneMediaAudioRequestCallback()1179 public void clearPrimaryZoneMediaAudioRequestCallback() throws Exception { 1180 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1181 getPrimaryZoneMediaAudioRequestCallbackImpl( 1182 mPrimaryZoneMediaAudioRequestCallbackMock); 1183 1184 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1185 1186 verify(mServiceMock).unregisterPrimaryZoneMediaAudioRequestCallback(serviceCallback); 1187 } 1188 1189 @Test clearPrimaryZoneMediaAudioRequestCallback_beforeRegisteringCallback()1190 public void clearPrimaryZoneMediaAudioRequestCallback_beforeRegisteringCallback() 1191 throws Exception { 1192 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1193 getPrimaryZoneMediaAudioRequestCallbackImpl( 1194 mPrimaryZoneMediaAudioRequestCallbackMock); 1195 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1196 verify(mServiceMock).unregisterPrimaryZoneMediaAudioRequestCallback(serviceCallback); 1197 clearInvocations(mServiceMock); 1198 1199 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1200 1201 verify(mServiceMock, never()).unregisterPrimaryZoneMediaAudioRequestCallback( 1202 serviceCallback); 1203 } 1204 1205 @Test clearPrimaryZoneMediaAudioRequestCallback_whenServiceThrowsRemoteException()1206 public void clearPrimaryZoneMediaAudioRequestCallback_whenServiceThrowsRemoteException() 1207 throws Exception { 1208 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1209 getPrimaryZoneMediaAudioRequestCallbackImpl( 1210 mPrimaryZoneMediaAudioRequestCallbackMock); 1211 doThrow(mRemoteException).when(mServiceMock) 1212 .unregisterPrimaryZoneMediaAudioRequestCallback(serviceCallback); 1213 1214 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1215 1216 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1217 } 1218 1219 @Test onRequestMediaOnPrimaryZone_forIPrimaryZoneMediaAudioRequestCallback()1220 public void onRequestMediaOnPrimaryZone_forIPrimaryZoneMediaAudioRequestCallback() 1221 throws Exception { 1222 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1223 getPrimaryZoneMediaAudioRequestCallbackImpl( 1224 mPrimaryZoneMediaAudioRequestCallbackMock); 1225 1226 serviceCallback.onRequestMediaOnPrimaryZone(mOccupantZoneInfoMock, TEST_REQUEST_ID); 1227 1228 verify(mPrimaryZoneMediaAudioRequestCallbackMock).onRequestMediaOnPrimaryZone( 1229 mOccupantZoneInfoMock, TEST_REQUEST_ID); 1230 } 1231 1232 @Test onRequestMediaOnPrimaryZone_afterClearPrimaryZoneMediaAudioRequestCallback()1233 public void onRequestMediaOnPrimaryZone_afterClearPrimaryZoneMediaAudioRequestCallback() 1234 throws Exception { 1235 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1236 getPrimaryZoneMediaAudioRequestCallbackImpl( 1237 mPrimaryZoneMediaAudioRequestCallbackMock); 1238 mCarAudioManager.clearPrimaryZoneMediaAudioRequestCallback(); 1239 1240 serviceCallback.onRequestMediaOnPrimaryZone(mOccupantZoneInfoMock, TEST_REQUEST_ID); 1241 1242 verify(mPrimaryZoneMediaAudioRequestCallbackMock, never()).onRequestMediaOnPrimaryZone( 1243 mOccupantZoneInfoMock, TEST_REQUEST_ID); 1244 } 1245 1246 @Test onMediaAudioRequestStatusChanged_forIPrimaryZoneMediaAudioRequestCallback()1247 public void onMediaAudioRequestStatusChanged_forIPrimaryZoneMediaAudioRequestCallback() 1248 throws Exception { 1249 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1250 getPrimaryZoneMediaAudioRequestCallbackImpl( 1251 mPrimaryZoneMediaAudioRequestCallbackMock); 1252 1253 serviceCallback.onMediaAudioRequestStatusChanged(mOccupantZoneInfoMock, TEST_REQUEST_ID, 1254 CarAudioManager.AUDIO_REQUEST_STATUS_STOPPED); 1255 1256 verify(mPrimaryZoneMediaAudioRequestCallbackMock).onMediaAudioRequestStatusChanged( 1257 mOccupantZoneInfoMock, TEST_REQUEST_ID, 1258 CarAudioManager.AUDIO_REQUEST_STATUS_STOPPED); 1259 } 1260 1261 @Test requestMediaAudioOnPrimaryZone()1262 public void requestMediaAudioOnPrimaryZone() throws Exception { 1263 int expectedRequestStatus = CarAudioManager.AUDIO_REQUEST_STATUS_APPROVED; 1264 doAnswer(invocation -> { 1265 IMediaAudioRequestStatusCallback callback = invocation.getArgument(0); 1266 OccupantZoneInfo info = invocation.getArgument(1); 1267 callback.onMediaAudioRequestStatusChanged(info, TEST_REQUEST_ID, expectedRequestStatus); 1268 return TEST_REQUEST_ID; 1269 }).when(mServiceMock).requestMediaAudioOnPrimaryZone(any( 1270 IMediaAudioRequestStatusCallback.class), any(OccupantZoneInfo.class)); 1271 1272 long requestId = mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1273 DIRECT_EXECUTOR, mMediaAudioRequestStatusCallbackMock); 1274 1275 expectWithMessage("Request id for media audio on primary zone").that(requestId) 1276 .isEqualTo(TEST_REQUEST_ID); 1277 verify(mMediaAudioRequestStatusCallbackMock).onMediaAudioRequestStatusChanged( 1278 mOccupantZoneInfoMock, TEST_REQUEST_ID, expectedRequestStatus); 1279 } 1280 1281 @Test requestMediaAudioOnPrimaryZone_withNullOccupantZoneInfo()1282 public void requestMediaAudioOnPrimaryZone_withNullOccupantZoneInfo() { 1283 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1284 mCarAudioManager.requestMediaAudioOnPrimaryZone(/* info= */ null, 1285 DIRECT_EXECUTOR, mMediaAudioRequestStatusCallbackMock)); 1286 1287 expectWithMessage("Exception for requesting media audio on primary zone with null info") 1288 .that(thrown).hasMessageThat().contains("Occupant zone info can not be null"); 1289 } 1290 1291 @Test requestMediaAudioOnPrimaryZone_withNullExecutor()1292 public void requestMediaAudioOnPrimaryZone_withNullExecutor() { 1293 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1294 mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1295 /* executor= */ null, mMediaAudioRequestStatusCallbackMock)); 1296 1297 expectWithMessage("Exception for requesting media audio on primary zone with null executor") 1298 .that(thrown).hasMessageThat().contains("Executor can not be null"); 1299 } 1300 1301 @Test requestMediaAudioOnPrimaryZone_withNullCallback()1302 public void requestMediaAudioOnPrimaryZone_withNullCallback() { 1303 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1304 mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1305 DIRECT_EXECUTOR, /* callback= */ null)); 1306 1307 expectWithMessage("Exception for requesting media audio on primary zone with " 1308 + "null callback").that(thrown).hasMessageThat() 1309 .contains("Media audio request status callback can not be null"); 1310 } 1311 1312 @Test requestMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsInvalidId()1313 public void requestMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsInvalidId() 1314 throws Exception { 1315 doThrow(mRemoteException).when(mServiceMock).requestMediaAudioOnPrimaryZone(any( 1316 IMediaAudioRequestStatusCallback.class), any(OccupantZoneInfo.class)); 1317 1318 expectWithMessage("Request id for media audio on primary zone when service throws " 1319 + "remote exception").that(mCarAudioManager.requestMediaAudioOnPrimaryZone( 1320 mOccupantZoneInfoMock, DIRECT_EXECUTOR, 1321 mMediaAudioRequestStatusCallbackMock)).isEqualTo( 1322 CarAudioManager.INVALID_REQUEST_ID); 1323 } 1324 1325 @Test cancelMediaAudioOnPrimaryZone()1326 public void cancelMediaAudioOnPrimaryZone() throws Exception { 1327 when(mServiceMock.requestMediaAudioOnPrimaryZone(any(), any())).thenReturn(TEST_REQUEST_ID); 1328 long requestId = mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1329 DIRECT_EXECUTOR, mMediaAudioRequestStatusCallbackMock); 1330 when(mServiceMock.cancelMediaAudioOnPrimaryZone(requestId)).thenReturn(true); 1331 1332 expectWithMessage("Status for canceling pending media audio on primary zone") 1333 .that(mCarAudioManager.cancelMediaAudioOnPrimaryZone(requestId)).isTrue(); 1334 } 1335 1336 @Test cancelMediaAudioOnPrimaryZone_withInvalidId()1337 public void cancelMediaAudioOnPrimaryZone_withInvalidId() throws Exception { 1338 when(mServiceMock.requestMediaAudioOnPrimaryZone(any(), any())) 1339 .thenReturn(CarAudioManager.INVALID_REQUEST_ID); 1340 long requestId = mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1341 DIRECT_EXECUTOR, mMediaAudioRequestStatusCallbackMock); 1342 1343 expectWithMessage("Status for canceling media audio request with invalid id") 1344 .that(mCarAudioManager.cancelMediaAudioOnPrimaryZone(requestId)).isTrue(); 1345 verify(mServiceMock, never()).cancelMediaAudioOnPrimaryZone(requestId); 1346 } 1347 1348 @Test cancelMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse()1349 public void cancelMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse() 1350 throws Exception { 1351 when(mServiceMock.requestMediaAudioOnPrimaryZone(any(), any())).thenReturn(TEST_REQUEST_ID); 1352 long requestId = mCarAudioManager.requestMediaAudioOnPrimaryZone(mOccupantZoneInfoMock, 1353 DIRECT_EXECUTOR, mMediaAudioRequestStatusCallbackMock); 1354 doThrow(mRemoteException).when(mServiceMock).cancelMediaAudioOnPrimaryZone(requestId); 1355 1356 expectWithMessage("Status for canceling pending media audio on primary zone " 1357 + "throws remote exception").that(mCarAudioManager.cancelMediaAudioOnPrimaryZone( 1358 requestId)).isFalse(); 1359 } 1360 1361 @Test allowMediaAudioOnPrimaryZone()1362 public void allowMediaAudioOnPrimaryZone() throws Exception { 1363 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1364 getPrimaryZoneMediaAudioRequestCallbackImpl( 1365 mPrimaryZoneMediaAudioRequestCallbackMock); 1366 when(mServiceMock.allowMediaAudioOnPrimaryZone(serviceCallback.asBinder(), TEST_REQUEST_ID, 1367 /* allow= */ true)).thenReturn(true); 1368 1369 expectWithMessage("Status for allowing media audio on primary zone") 1370 .that(mCarAudioManager.allowMediaAudioOnPrimaryZone(TEST_REQUEST_ID, 1371 /* allow= */ true)).isTrue(); 1372 } 1373 1374 @Test allowMediaAudioOnPrimaryZone_beforeSettingCallback()1375 public void allowMediaAudioOnPrimaryZone_beforeSettingCallback() { 1376 IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> 1377 mCarAudioManager.allowMediaAudioOnPrimaryZone(TEST_REQUEST_ID, /* allow= */ true)); 1378 1379 expectWithMessage("Exception for allowing media audio on primary zone before " 1380 + "setting primary zone media audio request callback").that(thrown) 1381 .hasMessageThat().contains("Primary zone media audio request callback"); 1382 } 1383 1384 @Test allowMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse()1385 public void allowMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse() 1386 throws Exception { 1387 IPrimaryZoneMediaAudioRequestCallback serviceCallback = 1388 getPrimaryZoneMediaAudioRequestCallbackImpl( 1389 mPrimaryZoneMediaAudioRequestCallbackMock); 1390 doThrow(mRemoteException).when(mServiceMock).allowMediaAudioOnPrimaryZone( 1391 serviceCallback.asBinder(), TEST_REQUEST_ID, /* allow= */ true); 1392 1393 expectWithMessage("Status for allowing media audio on primary zone when service throws" 1394 + "remote exception").that(mCarAudioManager.allowMediaAudioOnPrimaryZone( 1395 TEST_REQUEST_ID, /* allow= */ true)).isFalse(); 1396 } 1397 1398 @Test resetMediaAudioOnPrimaryZone()1399 public void resetMediaAudioOnPrimaryZone() throws Exception { 1400 when(mServiceMock.resetMediaAudioOnPrimaryZone(mOccupantZoneInfoMock)).thenReturn(true); 1401 1402 expectWithMessage("Status for resetting media audio on primary zone") 1403 .that(mCarAudioManager.resetMediaAudioOnPrimaryZone(mOccupantZoneInfoMock)) 1404 .isTrue(); 1405 } 1406 1407 @Test resetMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse()1408 public void resetMediaAudioOnPrimaryZone_whenServiceThrowsRemoteException_returnsFalse() 1409 throws Exception { 1410 doThrow(mRemoteException).when(mServiceMock).resetMediaAudioOnPrimaryZone( 1411 mOccupantZoneInfoMock); 1412 1413 expectWithMessage("Status for resetting media audio on primary zone when service " 1414 + "throws remote exception").that(mCarAudioManager.resetMediaAudioOnPrimaryZone( 1415 mOccupantZoneInfoMock)).isFalse(); 1416 } 1417 1418 @Test isMediaAudioAllowedInPrimaryZone()1419 public void isMediaAudioAllowedInPrimaryZone() throws Exception { 1420 when(mServiceMock.isMediaAudioAllowedInPrimaryZone(mOccupantZoneInfoMock)).thenReturn(true); 1421 1422 expectWithMessage("Media audio allowed in primary zone").that(mCarAudioManager 1423 .isMediaAudioAllowedInPrimaryZone(mOccupantZoneInfoMock)).isTrue(); 1424 } 1425 1426 @Test isMediaAudioAllowedInPrimaryZone_whenServiceThrowsRemoteException_returnsFalse()1427 public void isMediaAudioAllowedInPrimaryZone_whenServiceThrowsRemoteException_returnsFalse() 1428 throws Exception { 1429 doThrow(mRemoteException).when(mServiceMock).isMediaAudioAllowedInPrimaryZone( 1430 mOccupantZoneInfoMock); 1431 1432 expectWithMessage("Media audio allowed in primary zone when service " 1433 + "throws remote exception").that(mCarAudioManager.isMediaAudioAllowedInPrimaryZone( 1434 mOccupantZoneInfoMock)).isFalse(); 1435 } 1436 1437 @Test setAudioZoneMirrorStatusCallback_succeeds()1438 public void setAudioZoneMirrorStatusCallback_succeeds() throws Exception { 1439 when(mServiceMock.registerAudioZonesMirrorStatusCallback(any())).thenReturn(true); 1440 1441 expectWithMessage("Status for setting audio zone mirror status callback") 1442 .that(mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1443 mAudioZonesMirrorStatusCallback)).isTrue(); 1444 } 1445 1446 @Test setAudioZoneMirrorStatusCallback_withServiceReturnsFalse_fails()1447 public void setAudioZoneMirrorStatusCallback_withServiceReturnsFalse_fails() throws Exception { 1448 when(mServiceMock.registerAudioZonesMirrorStatusCallback(any())).thenReturn(false); 1449 1450 expectWithMessage("Status for setting audio zone mirror status callback") 1451 .that(mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1452 mAudioZonesMirrorStatusCallback)).isFalse(); 1453 } 1454 1455 @Test setAudioZoneMirrorStatusCallback_forMultipleTimes_fails()1456 public void setAudioZoneMirrorStatusCallback_forMultipleTimes_fails() throws Exception { 1457 when(mServiceMock.registerAudioZonesMirrorStatusCallback(any())).thenReturn(true); 1458 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1459 mAudioZonesMirrorStatusCallback); 1460 1461 IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> 1462 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1463 mock(AudioZonesMirrorStatusCallback.class))); 1464 1465 expectWithMessage("Exception for setting audio zone mirror status callback multiple times") 1466 .that(thrown).hasMessageThat().contains("callback is already set"); 1467 } 1468 1469 @Test setAudioZoneMirrorStatusCallback_withNullExecutor()1470 public void setAudioZoneMirrorStatusCallback_withNullExecutor() { 1471 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1472 mCarAudioManager.setAudioZoneMirrorStatusCallback(/* executor= */ null, 1473 mAudioZonesMirrorStatusCallback)); 1474 1475 expectWithMessage("Exception for setting audio zone mirror status callback with" 1476 + " null executor").that(thrown).hasMessageThat() 1477 .contains("Executor can not be null"); 1478 } 1479 1480 @Test setAudioZoneMirrorStatusCallback_withNullCallback()1481 public void setAudioZoneMirrorStatusCallback_withNullCallback() { 1482 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1483 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1484 /* callback= */ null)); 1485 1486 expectWithMessage("Exception for setting audio zone mirror status callback with " 1487 + "null callback").that(thrown).hasMessageThat() 1488 .contains("Audio zones mirror status callback can not be null"); 1489 } 1490 1491 @Test setAudioZoneMirrorStatusCallback_whenServiceThrowsRemoteException_returnsFalse()1492 public void setAudioZoneMirrorStatusCallback_whenServiceThrowsRemoteException_returnsFalse() 1493 throws Exception { 1494 doThrow(mRemoteException).when(mServiceMock).registerAudioZonesMirrorStatusCallback( 1495 any()); 1496 1497 expectWithMessage("Status for setting audio zone mirror status callback when service " 1498 + "throws remote exception").that(mCarAudioManager.setAudioZoneMirrorStatusCallback( 1499 DIRECT_EXECUTOR, mAudioZonesMirrorStatusCallback)).isFalse(); 1500 } 1501 1502 @Test clearAudioZonesMirrorStatusCallback()1503 public void clearAudioZonesMirrorStatusCallback() throws Exception { 1504 when(mServiceMock.registerAudioZonesMirrorStatusCallback(any())).thenReturn(true); 1505 ArgumentCaptor<IAudioZonesMirrorStatusCallback> captor = ArgumentCaptor.forClass( 1506 IAudioZonesMirrorStatusCallback.class); 1507 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1508 mAudioZonesMirrorStatusCallback); 1509 verify(mServiceMock).registerAudioZonesMirrorStatusCallback(captor.capture()); 1510 1511 mCarAudioManager.clearAudioZonesMirrorStatusCallback(); 1512 1513 verify(mServiceMock).unregisterAudioZonesMirrorStatusCallback(captor.getValue()); 1514 } 1515 1516 @Test clearAudioZonesMirrorStatusCallback_withoutCallbackSet()1517 public void clearAudioZonesMirrorStatusCallback_withoutCallbackSet() throws Exception { 1518 mCarAudioManager.clearAudioZonesMirrorStatusCallback(); 1519 1520 verify(mServiceMock, never()).unregisterAudioZonesMirrorStatusCallback(any()); 1521 } 1522 1523 @Test clearAudioZonesMirrorStatusCallback_whenServiceThrowsRemoteException()1524 public void clearAudioZonesMirrorStatusCallback_whenServiceThrowsRemoteException() 1525 throws Exception { 1526 when(mServiceMock.registerAudioZonesMirrorStatusCallback(any())).thenReturn(true); 1527 ArgumentCaptor<IAudioZonesMirrorStatusCallback> captor = ArgumentCaptor.forClass( 1528 IAudioZonesMirrorStatusCallback.class); 1529 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1530 mAudioZonesMirrorStatusCallback); 1531 verify(mServiceMock).registerAudioZonesMirrorStatusCallback(captor.capture()); 1532 doThrow(mRemoteException).when(mServiceMock).unregisterAudioZonesMirrorStatusCallback( 1533 captor.getValue()); 1534 1535 mCarAudioManager.clearAudioZonesMirrorStatusCallback(); 1536 1537 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1538 } 1539 1540 @Test canEnableAudioMirror()1541 public void canEnableAudioMirror() throws Exception { 1542 when(mServiceMock.canEnableAudioMirror()).thenReturn( 1543 CarAudioManager.AUDIO_MIRROR_OUT_OF_OUTPUT_DEVICES); 1544 1545 expectWithMessage("Audio mirror status").that(mCarAudioManager.canEnableAudioMirror()) 1546 .isEqualTo(CarAudioManager.AUDIO_MIRROR_OUT_OF_OUTPUT_DEVICES); 1547 } 1548 1549 @Test canEnableAudioMirror_whenServiceThrowsRemoteException_fails()1550 public void canEnableAudioMirror_whenServiceThrowsRemoteException_fails() throws Exception { 1551 doThrow(mRemoteException).when(mServiceMock).canEnableAudioMirror(); 1552 1553 expectWithMessage("Audio mirror status when service throws remote exception") 1554 .that(mCarAudioManager.canEnableAudioMirror()).isEqualTo( 1555 CarAudioManager.AUDIO_MIRROR_INTERNAL_ERROR); 1556 } 1557 1558 @Test enableMirrorForAudioZones()1559 public void enableMirrorForAudioZones() throws Exception { 1560 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID); 1561 IAudioZonesMirrorStatusCallback callback = getAudioZonesMirrorStatusCallbackWrapper(); 1562 doAnswer(invocation -> { 1563 int[] zones = invocation.getArgument(0); 1564 callback.onAudioZonesMirrorStatusChanged(zones, 1565 CarAudioManager.AUDIO_REQUEST_STATUS_APPROVED); 1566 return TEST_REQUEST_ID; 1567 }).when(mServiceMock).enableMirrorForAudioZones(any(int[].class)); 1568 1569 long requestId = mCarAudioManager.enableMirrorForAudioZones(zonesToMirrorList); 1570 1571 expectWithMessage("Request id for enabling mirror for audio zones").that(requestId) 1572 .isEqualTo(TEST_REQUEST_ID); 1573 verify(mAudioZonesMirrorStatusCallback).onAudioZonesMirrorStatusChanged(zonesToMirrorList, 1574 CarAudioManager.AUDIO_REQUEST_STATUS_APPROVED); 1575 } 1576 1577 @Test enableMirrorForAudioZones_withNullZoneList_fails()1578 public void enableMirrorForAudioZones_withNullZoneList_fails() { 1579 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1580 mCarAudioManager.enableMirrorForAudioZones(/* audioZonesToMirror= */ null)); 1581 1582 expectWithMessage("Exception for enabling mirror on null zone list").that(thrown) 1583 .hasMessageThat().contains("Audio zones to mirror should not be null"); 1584 } 1585 1586 @Test enableMirrorForAudioZones_whenServiceThrowsRemoteException_returnsInvalidId()1587 public void enableMirrorForAudioZones_whenServiceThrowsRemoteException_returnsInvalidId() 1588 throws Exception { 1589 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID); 1590 getAudioZonesMirrorStatusCallbackWrapper(); 1591 doThrow(mRemoteException).when(mServiceMock).enableMirrorForAudioZones(any( 1592 int[].class)); 1593 1594 expectWithMessage("Request id for enabling mirror for audio zones when service throws " 1595 + "remote exception").that(mCarAudioManager.enableMirrorForAudioZones( 1596 zonesToMirrorList)).isEqualTo(CarAudioManager.INVALID_REQUEST_ID); 1597 } 1598 1599 @Test extendAudioMirrorRequest()1600 public void extendAudioMirrorRequest() throws Exception { 1601 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_FRONT_ZONE_ID); 1602 IAudioZonesMirrorStatusCallback callback = getAudioZonesMirrorStatusCallbackWrapper(); 1603 doAnswer(invocation -> { 1604 int[] zones = invocation.getArgument(1); 1605 callback.onAudioZonesMirrorStatusChanged(zones, 1606 CarAudioManager.AUDIO_REQUEST_STATUS_REJECTED); 1607 return null; 1608 }).when(mServiceMock).extendAudioMirrorRequest(eq(TEST_REQUEST_ID), any(int[].class)); 1609 1610 mCarAudioManager.extendAudioMirrorRequest(TEST_REQUEST_ID, zonesToMirrorList); 1611 1612 verify(mAudioZonesMirrorStatusCallback).onAudioZonesMirrorStatusChanged(zonesToMirrorList, 1613 CarAudioManager.AUDIO_REQUEST_STATUS_REJECTED); 1614 } 1615 1616 @Test extendAudioMirrorRequest_withNullZoneList_fails()1617 public void extendAudioMirrorRequest_withNullZoneList_fails() { 1618 NullPointerException thrown = assertThrows(NullPointerException.class, () -> 1619 mCarAudioManager.extendAudioMirrorRequest(TEST_REQUEST_ID, 1620 /* audioZonesToMirror= */ null)); 1621 1622 expectWithMessage("Exception for extending mirror on null zone list").that(thrown) 1623 .hasMessageThat().contains("Audio zones to mirror should not be null"); 1624 } 1625 1626 @Test extendAudioMirrorRequest_whenServiceThrowsRemoteException()1627 public void extendAudioMirrorRequest_whenServiceThrowsRemoteException() throws Exception { 1628 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_FRONT_ZONE_ID); 1629 getAudioZonesMirrorStatusCallbackWrapper(); 1630 doThrow(mRemoteException).when(mServiceMock).extendAudioMirrorRequest( 1631 eq(TEST_REQUEST_ID), any(int[].class)); 1632 1633 mCarAudioManager.extendAudioMirrorRequest(TEST_REQUEST_ID, zonesToMirrorList); 1634 1635 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1636 } 1637 1638 @Test disableAudioMirror()1639 public void disableAudioMirror() throws Exception { 1640 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID); 1641 IAudioZonesMirrorStatusCallback callback = getAudioZonesMirrorStatusCallbackWrapper(); 1642 long requestId = mCarAudioManager.enableMirrorForAudioZones(zonesToMirrorList); 1643 doAnswer(invocation -> { 1644 callback.onAudioZonesMirrorStatusChanged(new int[]{TEST_REAR_LEFT_ZONE_ID, 1645 TEST_REAR_RIGHT_ZONE_ID}, CarAudioManager.AUDIO_REQUEST_STATUS_CANCELLED); 1646 return null; 1647 }).when(mServiceMock).disableAudioMirror(requestId); 1648 1649 mCarAudioManager.disableAudioMirror(requestId); 1650 1651 verify(mAudioZonesMirrorStatusCallback).onAudioZonesMirrorStatusChanged(zonesToMirrorList, 1652 CarAudioManager.AUDIO_REQUEST_STATUS_CANCELLED); 1653 } 1654 1655 @Test disableAudioMirror_whenServiceThrowsRemoteException()1656 public void disableAudioMirror_whenServiceThrowsRemoteException() throws Exception { 1657 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID); 1658 getAudioZonesMirrorStatusCallbackWrapper(); 1659 long requestId = mCarAudioManager.enableMirrorForAudioZones(zonesToMirrorList); 1660 doThrow(mRemoteException).when(mServiceMock).disableAudioMirror(requestId); 1661 1662 mCarAudioManager.disableAudioMirror(requestId); 1663 1664 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1665 } 1666 1667 @Test disableAudioMirrorForZone()1668 public void disableAudioMirrorForZone() throws Exception { 1669 List<Integer> zonesToMirrorList = List.of(TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID); 1670 IAudioZonesMirrorStatusCallback callback = getAudioZonesMirrorStatusCallbackWrapper(); 1671 doAnswer(invocation -> { 1672 callback.onAudioZonesMirrorStatusChanged(new int[]{TEST_REAR_LEFT_ZONE_ID, 1673 TEST_REAR_RIGHT_ZONE_ID}, CarAudioManager.AUDIO_REQUEST_STATUS_CANCELLED); 1674 return null; 1675 }).when(mServiceMock).disableAudioMirrorForZone(TEST_REAR_RIGHT_ZONE_ID); 1676 1677 mCarAudioManager.disableAudioMirrorForZone(TEST_REAR_RIGHT_ZONE_ID); 1678 1679 verify(mAudioZonesMirrorStatusCallback).onAudioZonesMirrorStatusChanged(zonesToMirrorList, 1680 CarAudioManager.AUDIO_REQUEST_STATUS_CANCELLED); 1681 } 1682 1683 @Test disableAudioMirrorForZone_whenServiceThrowsRemoteException()1684 public void disableAudioMirrorForZone_whenServiceThrowsRemoteException() throws Exception { 1685 getAudioZonesMirrorStatusCallbackWrapper(); 1686 doThrow(mRemoteException).when(mServiceMock).disableAudioMirrorForZone( 1687 TEST_REAR_RIGHT_ZONE_ID); 1688 1689 mCarAudioManager.disableAudioMirrorForZone(TEST_REAR_RIGHT_ZONE_ID); 1690 1691 verify(mCar).handleRemoteExceptionFromCarService(mRemoteException); 1692 } 1693 1694 @Test getMirrorAudioZonesForAudioZone()1695 public void getMirrorAudioZonesForAudioZone() throws Exception { 1696 when(mServiceMock.getMirrorAudioZonesForAudioZone(TEST_REAR_RIGHT_ZONE_ID)).thenReturn( 1697 new int[]{TEST_REAR_LEFT_ZONE_ID, TEST_FRONT_ZONE_ID}); 1698 1699 expectWithMessage("Mirror zones for rear right zone").that(mCarAudioManager 1700 .getMirrorAudioZonesForAudioZone(TEST_REAR_RIGHT_ZONE_ID)).containsExactly( 1701 TEST_REAR_LEFT_ZONE_ID, TEST_FRONT_ZONE_ID).inOrder(); 1702 } 1703 1704 @Test getMirrorAudioZonesForAudioZone_whenServiceThrowsRemoteException_returnsEmptyList()1705 public void getMirrorAudioZonesForAudioZone_whenServiceThrowsRemoteException_returnsEmptyList() 1706 throws Exception { 1707 doThrow(mRemoteException).when(mServiceMock).getMirrorAudioZonesForAudioZone( 1708 TEST_REAR_RIGHT_ZONE_ID); 1709 1710 expectWithMessage("Mirror zones for rear right zone when service throws remote exception") 1711 .that(mCarAudioManager.getMirrorAudioZonesForAudioZone(TEST_REAR_RIGHT_ZONE_ID)) 1712 .isEmpty(); 1713 } 1714 1715 @Test getMirrorAudioZonesForMirrorRequest()1716 public void getMirrorAudioZonesForMirrorRequest() throws Exception { 1717 when(mServiceMock.getMirrorAudioZonesForMirrorRequest(TEST_REQUEST_ID)).thenReturn( 1718 new int[]{TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID}); 1719 1720 expectWithMessage("Mirror zones for request id").that(mCarAudioManager 1721 .getMirrorAudioZonesForMirrorRequest(TEST_REQUEST_ID)).containsExactly( 1722 TEST_REAR_LEFT_ZONE_ID, TEST_REAR_RIGHT_ZONE_ID).inOrder(); 1723 } 1724 1725 @Test getMirrorAudioZonesForMirrorRequest_whenServiceThrowsRemoteException()1726 public void getMirrorAudioZonesForMirrorRequest_whenServiceThrowsRemoteException() 1727 throws Exception { 1728 doThrow(mRemoteException).when(mServiceMock).getMirrorAudioZonesForMirrorRequest( 1729 TEST_REQUEST_ID); 1730 1731 expectWithMessage("Mirror zones for request id when service throws remote exception") 1732 .that(mCarAudioManager.getMirrorAudioZonesForMirrorRequest(TEST_REQUEST_ID)) 1733 .isEmpty(); 1734 } 1735 1736 @Test getOutputDeviceForUsage()1737 public void getOutputDeviceForUsage() throws Exception { 1738 when(mAudioManagerMock.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).thenReturn( 1739 new AudioDeviceInfo[]{TEST_MEDIA_OUTPUT_DEVICE, TEST_NAV_OUTPUT_DEVICE}); 1740 when(mServiceMock.getOutputDeviceAddressForUsage(PRIMARY_AUDIO_ZONE, 1741 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)).thenReturn(NAVIGATION_TEST_DEVICE); 1742 1743 AudioDeviceInfo outputDevice = mCarAudioManager.getOutputDeviceForUsage(PRIMARY_AUDIO_ZONE, 1744 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE); 1745 1746 expectWithMessage("Navigation output device").that(outputDevice) 1747 .isEqualTo(TEST_NAV_OUTPUT_DEVICE); 1748 } 1749 1750 @Test getOutputDeviceForUsage_withDeviceAddressNotFound_returnsNull()1751 public void getOutputDeviceForUsage_withDeviceAddressNotFound_returnsNull() throws Exception { 1752 String invalidDeviceAddress = "invalid_bus"; 1753 when(mAudioManagerMock.getDevices(AudioManager.GET_DEVICES_OUTPUTS)).thenReturn( 1754 new AudioDeviceInfo[]{TEST_MEDIA_OUTPUT_DEVICE, TEST_NAV_OUTPUT_DEVICE}); 1755 when(mServiceMock.getOutputDeviceAddressForUsage(PRIMARY_AUDIO_ZONE, 1756 USAGE_GAME)).thenReturn(invalidDeviceAddress); 1757 1758 expectWithMessage("Null output device").that(mCarAudioManager.getOutputDeviceForUsage( 1759 PRIMARY_AUDIO_ZONE, USAGE_GAME)).isNull(); 1760 } 1761 1762 @Test getOutputDeviceForUsage_whenServiceThrowsRemoteException_returnsNull()1763 public void getOutputDeviceForUsage_whenServiceThrowsRemoteException_returnsNull() 1764 throws Exception { 1765 doThrow(mRemoteException).when(mServiceMock).getOutputDeviceAddressForUsage( 1766 PRIMARY_AUDIO_ZONE, USAGE_ASSISTANCE_NAVIGATION_GUIDANCE); 1767 1768 expectWithMessage("Navigation output device when service throws remote exception") 1769 .that(mCarAudioManager.getOutputDeviceForUsage(PRIMARY_AUDIO_ZONE, 1770 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)).isNull(); 1771 } 1772 1773 @Test getInputDevicesForZoneId()1774 public void getInputDevicesForZoneId() throws Exception { 1775 AudioDeviceAttributes microphoneAttr = mock(AudioDeviceAttributes.class); 1776 when(microphoneAttr.getAddress()).thenReturn(MICROPHONE_ADDRESS); 1777 AudioDeviceAttributes tunerAttr = mock(AudioDeviceAttributes.class); 1778 when(tunerAttr.getAddress()).thenReturn(FM_TUNER_ADDRESS); 1779 List<AudioDeviceAttributes> inputDevicesFromService = List.of(microphoneAttr, tunerAttr); 1780 when(mServiceMock.getInputDevicesForZoneId(PRIMARY_AUDIO_ZONE)).thenReturn( 1781 inputDevicesFromService); 1782 when(mAudioManagerMock.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn( 1783 new AudioDeviceInfo[]{TEST_MICROPHONE_INPUT_DEVICE, TEST_TUNER_INPUT_DEVICE}); 1784 1785 List<AudioDeviceInfo> inputDevices = mCarAudioManager.getInputDevicesForZoneId( 1786 PRIMARY_AUDIO_ZONE); 1787 1788 expectWithMessage("Input devices for primary zone").that(inputDevices) 1789 .containsExactly(TEST_MICROPHONE_INPUT_DEVICE, TEST_TUNER_INPUT_DEVICE); 1790 } 1791 1792 @Test getInputDevicesForZoneId_withInvalidDevicesInAudioManager()1793 public void getInputDevicesForZoneId_withInvalidDevicesInAudioManager() throws Exception { 1794 AudioDeviceAttributes microphoneAttr = mock(AudioDeviceAttributes.class); 1795 when(microphoneAttr.getAddress()).thenReturn(MICROPHONE_ADDRESS); 1796 when(mServiceMock.getInputDevicesForZoneId(PRIMARY_AUDIO_ZONE)).thenReturn( 1797 List.of(microphoneAttr)); 1798 when(mAudioManagerMock.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn( 1799 new AudioDeviceInfo[]{TEST_MEDIA_OUTPUT_DEVICE, TEST_TUNER_INPUT_DEVICE}); 1800 1801 List<AudioDeviceInfo> inputDevices = mCarAudioManager.getInputDevicesForZoneId( 1802 PRIMARY_AUDIO_ZONE); 1803 1804 expectWithMessage("No input devices found for primary zone").that(inputDevices).isEmpty(); 1805 } 1806 1807 @Test getInputDevicesForZoneId_whenServiceThrowsRemoteException_returnsEmptyList()1808 public void getInputDevicesForZoneId_whenServiceThrowsRemoteException_returnsEmptyList() 1809 throws Exception { 1810 doThrow(mRemoteException).when(mServiceMock).getInputDevicesForZoneId( 1811 PRIMARY_AUDIO_ZONE); 1812 1813 expectWithMessage("Input devices for primary zone when service throws remote exception") 1814 .that(mCarAudioManager.getInputDevicesForZoneId(PRIMARY_AUDIO_ZONE)).isEmpty(); 1815 } 1816 getCarVolumeCallbackImpl(CarAudioManager.CarVolumeCallback callbackMock)1817 private ICarVolumeCallback getCarVolumeCallbackImpl(CarAudioManager.CarVolumeCallback 1818 callbackMock) throws Exception { 1819 ArgumentCaptor<IBinder> captor = ArgumentCaptor.forClass(IBinder.class); 1820 mCarAudioManager.registerCarVolumeCallback(callbackMock); 1821 verify(mServiceMock).registerVolumeCallback(captor.capture()); 1822 return ICarVolumeCallback.Stub.asInterface(captor.getValue()); 1823 } 1824 getCarVolumeEventCallbackImpl(CarVolumeGroupEventCallback callbackMock)1825 private ICarVolumeEventCallback getCarVolumeEventCallbackImpl(CarVolumeGroupEventCallback 1826 callbackMock) throws Exception { 1827 when(mServiceMock.registerCarVolumeEventCallback(any())).thenReturn(true); 1828 mCarAudioManager.registerCarVolumeGroupEventCallback(DIRECT_EXECUTOR, callbackMock); 1829 ArgumentCaptor<ICarVolumeEventCallback> captor = ArgumentCaptor.forClass( 1830 ICarVolumeEventCallback.class); 1831 verify(mServiceMock).registerCarVolumeEventCallback(captor.capture()); 1832 return captor.getValue(); 1833 } 1834 getPrimaryZoneMediaAudioRequestCallbackImpl( PrimaryZoneMediaAudioRequestCallback callbackMock)1835 private IPrimaryZoneMediaAudioRequestCallback getPrimaryZoneMediaAudioRequestCallbackImpl( 1836 PrimaryZoneMediaAudioRequestCallback callbackMock) throws Exception { 1837 when(mServiceMock.registerPrimaryZoneMediaAudioRequestCallback(any())).thenReturn(true); 1838 ArgumentCaptor<IPrimaryZoneMediaAudioRequestCallback> captor = ArgumentCaptor.forClass( 1839 IPrimaryZoneMediaAudioRequestCallback.class); 1840 mCarAudioManager.setPrimaryZoneMediaAudioRequestCallback(DIRECT_EXECUTOR, callbackMock); 1841 verify(mServiceMock).registerPrimaryZoneMediaAudioRequestCallback(captor.capture()); 1842 return captor.getValue(); 1843 } 1844 getAudioZonesMirrorStatusCallbackWrapper()1845 private IAudioZonesMirrorStatusCallback getAudioZonesMirrorStatusCallbackWrapper() 1846 throws Exception { 1847 ArgumentCaptor<IAudioZonesMirrorStatusCallback> captor = ArgumentCaptor.forClass( 1848 IAudioZonesMirrorStatusCallback.class); 1849 when(mServiceMock.registerAudioZonesMirrorStatusCallback( 1850 any(IAudioZonesMirrorStatusCallback.class))).thenReturn(true); 1851 mCarAudioManager.setAudioZoneMirrorStatusCallback(DIRECT_EXECUTOR, 1852 mAudioZonesMirrorStatusCallback); 1853 verify(mServiceMock).registerAudioZonesMirrorStatusCallback(captor.capture()); 1854 return captor.getValue(); 1855 } 1856 1857 private static final class TestAudioZoneConfigurationsChangeCallback 1858 implements AudioZoneConfigurationsChangeCallback { 1859 1860 private static final long TEST_CALLBACK_TIMEOUT_MS = 500; 1861 private List<CarAudioZoneConfigInfo> mInfos; 1862 private int mStatus; 1863 1864 private CountDownLatch mStatusLatch = new CountDownLatch(1); 1865 @Override onAudioZoneConfigurationsChanged(List<CarAudioZoneConfigInfo> configs, int status)1866 public void onAudioZoneConfigurationsChanged(List<CarAudioZoneConfigInfo> configs, 1867 int status) { 1868 mInfos = configs; 1869 mStatus = status; 1870 mStatusLatch.countDown(); 1871 } 1872 waitForCallback()1873 private void waitForCallback() throws Exception { 1874 mStatusLatch.await(TEST_CALLBACK_TIMEOUT_MS, TimeUnit.MILLISECONDS); 1875 } 1876 } 1877 } 1878