1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.audio; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.Mockito.verify; 22 import static org.mockito.Mockito.when; 23 import static org.testng.Assert.expectThrows; 24 25 import android.annotation.UserIdInt; 26 import android.os.UserHandle; 27 import android.util.SparseBooleanArray; 28 import android.util.SparseIntArray; 29 30 import org.junit.Before; 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 import org.mockito.Mock; 34 import org.mockito.Mockito; 35 import org.mockito.junit.MockitoJUnitRunner; 36 37 import java.util.List; 38 39 @RunWith(MockitoJUnitRunner.class) 40 public class CarVolumeGroupUnitTest { 41 private static final int ZONE_ID = 0; 42 private static final int GROUP_ID = 0; 43 private static final int STEP_VALUE = 2; 44 private static final int MIN_GAIN = 3; 45 private static final int MAX_GAIN = 10; 46 private static final int DEFAULT_GAIN = 5; 47 private static final int DEFAULT_GAIN_INDEX = (DEFAULT_GAIN - MIN_GAIN) / STEP_VALUE; 48 private static final int MIN_GAIN_INDEX = 0; 49 private static final int MAX_GAIN_INDEX = (MAX_GAIN - MIN_GAIN) / STEP_VALUE; 50 private static final int TEST_GAIN_INDEX = 2; 51 private static final int TEST_USER_10 = 10; 52 private static final int TEST_USER_11 = 11; 53 private static final String MEDIA_DEVICE_ADDRESS = "music"; 54 private static final String NAVIGATION_DEVICE_ADDRESS = "navigation"; 55 private static final String OTHER_ADDRESS = "other_address"; 56 57 private CarAudioDeviceInfo mMediaDeviceInfo; 58 private CarAudioDeviceInfo mNavigationDeviceInfo; 59 60 @Mock 61 CarAudioSettings mSettingsMock; 62 63 @Before setUp()64 public void setUp() { 65 mMediaDeviceInfo = new InfoBuilder(MEDIA_DEVICE_ADDRESS).build(); 66 mNavigationDeviceInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS).build(); 67 } 68 69 @Test setDeviceInfoForContext_associatesDeviceAddresses()70 public void setDeviceInfoForContext_associatesDeviceAddresses() { 71 CarVolumeGroup.Builder builder = getBuilder(); 72 73 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 74 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, mNavigationDeviceInfo); 75 CarVolumeGroup carVolumeGroup = builder.build(); 76 77 assertThat(carVolumeGroup.getAddresses()).containsExactly(MEDIA_DEVICE_ADDRESS, 78 NAVIGATION_DEVICE_ADDRESS); 79 } 80 81 @Test setDeviceInfoForContext_associatesContexts()82 public void setDeviceInfoForContext_associatesContexts() { 83 CarVolumeGroup.Builder builder = getBuilder(); 84 85 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 86 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, mNavigationDeviceInfo); 87 CarVolumeGroup carVolumeGroup = builder.build(); 88 89 assertThat(carVolumeGroup.getContexts()).asList().containsExactly(CarAudioContext.MUSIC, 90 CarAudioContext.NAVIGATION); 91 } 92 93 @Test setDeviceInfoForContext_withDifferentStepSize_throws()94 public void setDeviceInfoForContext_withDifferentStepSize_throws() { 95 CarVolumeGroup.Builder builder = getBuilder(); 96 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 97 CarAudioDeviceInfo differentStepValueDevice = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 98 .setStepValue(mMediaDeviceInfo.getStepValue() + 1).build(); 99 100 IllegalArgumentException thrown = expectThrows(IllegalArgumentException.class, 101 () -> builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, 102 differentStepValueDevice)); 103 104 assertThat(thrown).hasMessageThat() 105 .contains("Gain controls within one group must have same step value"); 106 } 107 108 @Test setDeviceInfoForContext_withSameContext_throws()109 public void setDeviceInfoForContext_withSameContext_throws() { 110 CarVolumeGroup.Builder builder = getBuilder(); 111 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 112 113 IllegalArgumentException thrown = expectThrows(IllegalArgumentException.class, 114 () -> builder.setDeviceInfoForContext(CarAudioContext.MUSIC, 115 mNavigationDeviceInfo)); 116 117 assertThat(thrown).hasMessageThat() 118 .contains("has already been set to"); 119 } 120 121 @Test setDeviceInfoForContext_withFirstCall_setsMinGain()122 public void setDeviceInfoForContext_withFirstCall_setsMinGain() { 123 CarVolumeGroup.Builder builder = getBuilder(); 124 125 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 126 127 assertThat(builder.mMinGain).isEqualTo(mMediaDeviceInfo.getMinGain()); 128 } 129 130 @Test setDeviceInfoForContext_withFirstCall_setsMaxGain()131 public void setDeviceInfoForContext_withFirstCall_setsMaxGain() { 132 CarVolumeGroup.Builder builder = getBuilder(); 133 134 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 135 136 assertThat(builder.mMaxGain).isEqualTo(mMediaDeviceInfo.getMaxGain()); 137 } 138 139 @Test setDeviceInfoForContext_withFirstCall_setsDefaultGain()140 public void setDeviceInfoForContext_withFirstCall_setsDefaultGain() { 141 CarVolumeGroup.Builder builder = getBuilder(); 142 143 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 144 145 assertThat(builder.mDefaultGain).isEqualTo(mMediaDeviceInfo.getDefaultGain()); 146 } 147 148 @Test setDeviceInfoForContext_SecondCallWithSmallerMinGain_updatesMinGain()149 public void setDeviceInfoForContext_SecondCallWithSmallerMinGain_updatesMinGain() { 150 CarVolumeGroup.Builder builder = getBuilder(); 151 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 152 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 153 .setMinGain(mMediaDeviceInfo.getMinGain() - 1).build(); 154 155 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 156 157 assertThat(builder.mMinGain).isEqualTo(secondInfo.getMinGain()); 158 } 159 160 @Test setDeviceInfoForContext_SecondCallWithLargerMinGain_keepsFirstMinGain()161 public void setDeviceInfoForContext_SecondCallWithLargerMinGain_keepsFirstMinGain() { 162 CarVolumeGroup.Builder builder = getBuilder(); 163 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 164 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 165 .setMinGain(mMediaDeviceInfo.getMinGain() + 1).build(); 166 167 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 168 169 assertThat(builder.mMinGain).isEqualTo(mMediaDeviceInfo.getMinGain()); 170 } 171 172 @Test setDeviceInfoForContext_SecondCallWithLargerMaxGain_updatesMaxGain()173 public void setDeviceInfoForContext_SecondCallWithLargerMaxGain_updatesMaxGain() { 174 CarVolumeGroup.Builder builder = getBuilder(); 175 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 176 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 177 .setMaxGain(mMediaDeviceInfo.getMaxGain() + 1).build(); 178 179 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 180 181 assertThat(builder.mMaxGain).isEqualTo(secondInfo.getMaxGain()); 182 } 183 184 @Test setDeviceInfoForContext_SecondCallWithSmallerMaxGain_keepsFirstMaxGain()185 public void setDeviceInfoForContext_SecondCallWithSmallerMaxGain_keepsFirstMaxGain() { 186 CarVolumeGroup.Builder builder = getBuilder(); 187 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 188 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 189 .setMaxGain(mMediaDeviceInfo.getMaxGain() - 1).build(); 190 191 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 192 193 assertThat(builder.mMaxGain).isEqualTo(mMediaDeviceInfo.getMaxGain()); 194 } 195 196 @Test setDeviceInfoForContext_SecondCallWithLargerDefaultGain_updatesDefaultGain()197 public void setDeviceInfoForContext_SecondCallWithLargerDefaultGain_updatesDefaultGain() { 198 CarVolumeGroup.Builder builder = getBuilder(); 199 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 200 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 201 .setDefaultGain(mMediaDeviceInfo.getDefaultGain() + 1).build(); 202 203 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 204 205 assertThat(builder.mDefaultGain).isEqualTo(secondInfo.getDefaultGain()); 206 } 207 208 @Test setDeviceInfoForContext_SecondCallWithSmallerDefaultGain_keepsFirstDefaultGain()209 public void setDeviceInfoForContext_SecondCallWithSmallerDefaultGain_keepsFirstDefaultGain() { 210 CarVolumeGroup.Builder builder = getBuilder(); 211 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 212 CarAudioDeviceInfo secondInfo = new InfoBuilder(NAVIGATION_DEVICE_ADDRESS) 213 .setDefaultGain(mMediaDeviceInfo.getDefaultGain() - 1).build(); 214 215 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, secondInfo); 216 217 assertThat(builder.mDefaultGain).isEqualTo(mMediaDeviceInfo.getDefaultGain()); 218 } 219 220 @Test builderBuild_withNoCallToSetDeviceInfoForContext_throws()221 public void builderBuild_withNoCallToSetDeviceInfoForContext_throws() { 222 CarVolumeGroup.Builder builder = getBuilder(); 223 224 Exception e = expectThrows(IllegalArgumentException.class, builder::build); 225 226 assertThat(e).hasMessageThat().isEqualTo( 227 "setDeviceInfoForContext has to be called at least once before building"); 228 } 229 230 @Test builderBuild_withNoStoredGain_usesDefaultGain()231 public void builderBuild_withNoStoredGain_usesDefaultGain() { 232 CarVolumeGroup.Builder builder = getBuilder().setDeviceInfoForContext(CarAudioContext.MUSIC, 233 mMediaDeviceInfo); 234 when(mSettingsMock.getStoredVolumeGainIndexForUser(UserHandle.USER_CURRENT, ZONE_ID, 235 GROUP_ID)).thenReturn(-1); 236 237 238 CarVolumeGroup carVolumeGroup = builder.build(); 239 240 assertThat(carVolumeGroup.getCurrentGainIndex()).isEqualTo(DEFAULT_GAIN_INDEX); 241 } 242 243 @Test builderBuild_withTooLargeStoredGain_usesDefaultGain()244 public void builderBuild_withTooLargeStoredGain_usesDefaultGain() { 245 CarVolumeGroup.Builder builder = getBuilder().setDeviceInfoForContext(CarAudioContext.MUSIC, 246 mMediaDeviceInfo); 247 when(mSettingsMock.getStoredVolumeGainIndexForUser(UserHandle.USER_CURRENT, ZONE_ID, 248 GROUP_ID)).thenReturn(MAX_GAIN_INDEX + 1); 249 250 CarVolumeGroup carVolumeGroup = builder.build(); 251 252 assertThat(carVolumeGroup.getCurrentGainIndex()).isEqualTo(DEFAULT_GAIN_INDEX); 253 } 254 255 @Test builderBuild_withTooSmallStoredGain_usesDefaultGain()256 public void builderBuild_withTooSmallStoredGain_usesDefaultGain() { 257 CarVolumeGroup.Builder builder = getBuilder().setDeviceInfoForContext(CarAudioContext.MUSIC, 258 mMediaDeviceInfo); 259 when(mSettingsMock.getStoredVolumeGainIndexForUser(UserHandle.USER_CURRENT, ZONE_ID, 260 GROUP_ID)).thenReturn(MIN_GAIN_INDEX - 1); 261 262 CarVolumeGroup carVolumeGroup = builder.build(); 263 264 assertThat(carVolumeGroup.getCurrentGainIndex()).isEqualTo(DEFAULT_GAIN_INDEX); 265 } 266 267 @Test builderBuild_withValidStoredGain_usesStoredGain()268 public void builderBuild_withValidStoredGain_usesStoredGain() { 269 CarVolumeGroup.Builder builder = getBuilder().setDeviceInfoForContext(CarAudioContext.MUSIC, 270 mMediaDeviceInfo); 271 when(mSettingsMock.getStoredVolumeGainIndexForUser(UserHandle.USER_CURRENT, ZONE_ID, 272 GROUP_ID)).thenReturn(MAX_GAIN_INDEX - 1); 273 274 CarVolumeGroup carVolumeGroup = builder.build(); 275 276 assertThat(carVolumeGroup.getCurrentGainIndex()).isEqualTo(MAX_GAIN_INDEX - 1); 277 } 278 279 @Test getAddressForContext_withSupportedContext_returnsAddress()280 public void getAddressForContext_withSupportedContext_returnsAddress() { 281 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 282 283 assertThat(carVolumeGroup.getAddressForContext(CarAudioContext.MUSIC)) 284 .isEqualTo(mMediaDeviceInfo.getAddress()); 285 } 286 287 @Test getAddressForContext_withUnsupportedContext_returnsNull()288 public void getAddressForContext_withUnsupportedContext_returnsNull() { 289 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 290 291 assertThat(carVolumeGroup.getAddressForContext(CarAudioContext.NAVIGATION)).isNull(); 292 } 293 294 @Test isMuted_whenDefault_returnsFalse()295 public void isMuted_whenDefault_returnsFalse() { 296 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 297 298 assertThat(carVolumeGroup.isMuted()).isFalse(); 299 } 300 301 @Test isMuted_afterMuting_returnsTrue()302 public void isMuted_afterMuting_returnsTrue() { 303 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 304 305 carVolumeGroup.setMute(true); 306 307 assertThat(carVolumeGroup.isMuted()).isTrue(); 308 } 309 310 @Test isMuted_afterUnMuting_returnsFalse()311 public void isMuted_afterUnMuting_returnsFalse() { 312 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 313 314 carVolumeGroup.setMute(false); 315 316 assertThat(carVolumeGroup.isMuted()).isFalse(); 317 } 318 319 @Test setMute_withMutedState_storesValueToSetting()320 public void setMute_withMutedState_storesValueToSetting() { 321 CarAudioSettings settings = new SettingsBuilder(0, 0) 322 .setMuteForUser10(false) 323 .setIsPersistVolumeGroupEnabled(true) 324 .build(); 325 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithNavigationBound(settings, true); 326 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 327 328 carVolumeGroup.setMute(true); 329 330 verify(settings) 331 .storeVolumeGroupMuteForUser(TEST_USER_10, 0, 0, true); 332 } 333 334 @Test setMute_withUnMutedState_storesValueToSetting()335 public void setMute_withUnMutedState_storesValueToSetting() { 336 CarAudioSettings settings = new SettingsBuilder(0, 0) 337 .setMuteForUser10(false) 338 .setIsPersistVolumeGroupEnabled(true) 339 .build(); 340 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithNavigationBound(settings, true); 341 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 342 343 carVolumeGroup.setMute(false); 344 345 verify(settings) 346 .storeVolumeGroupMuteForUser(TEST_USER_10, 0, 0, false); 347 } 348 349 @Test getContextsForAddress_returnsContextsBoundToThatAddress()350 public void getContextsForAddress_returnsContextsBoundToThatAddress() { 351 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 352 353 List<Integer> contextsList = carVolumeGroup.getContextsForAddress(MEDIA_DEVICE_ADDRESS); 354 355 assertThat(contextsList).containsExactly(CarAudioContext.MUSIC, 356 CarAudioContext.CALL, CarAudioContext.CALL_RING); 357 } 358 359 @Test getContextsForAddress_returnsEmptyArrayIfAddressNotBound()360 public void getContextsForAddress_returnsEmptyArrayIfAddressNotBound() { 361 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 362 363 List<Integer> contextsList = carVolumeGroup.getContextsForAddress(OTHER_ADDRESS); 364 365 assertThat(contextsList).isEmpty(); 366 } 367 368 @Test getCarAudioDeviceInfoForAddress_returnsExpectedDevice()369 public void getCarAudioDeviceInfoForAddress_returnsExpectedDevice() { 370 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 371 372 CarAudioDeviceInfo actualDevice = carVolumeGroup.getCarAudioDeviceInfoForAddress( 373 MEDIA_DEVICE_ADDRESS); 374 375 assertThat(actualDevice).isEqualTo(mMediaDeviceInfo); 376 } 377 378 @Test getCarAudioDeviceInfoForAddress_returnsNullIfAddressNotBound()379 public void getCarAudioDeviceInfoForAddress_returnsNullIfAddressNotBound() { 380 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 381 382 CarAudioDeviceInfo actualDevice = carVolumeGroup.getCarAudioDeviceInfoForAddress( 383 OTHER_ADDRESS); 384 385 assertThat(actualDevice).isNull(); 386 } 387 388 @Test setCurrentGainIndex_setsGainOnAllBoundDevices()389 public void setCurrentGainIndex_setsGainOnAllBoundDevices() { 390 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 391 392 carVolumeGroup.setCurrentGainIndex(TEST_GAIN_INDEX); 393 394 verify(mMediaDeviceInfo).setCurrentGain(7); 395 verify(mNavigationDeviceInfo).setCurrentGain(7); 396 } 397 398 @Test setCurrentGainIndex_updatesCurrentGainIndex()399 public void setCurrentGainIndex_updatesCurrentGainIndex() { 400 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 401 402 carVolumeGroup.setCurrentGainIndex(TEST_GAIN_INDEX); 403 404 assertThat(carVolumeGroup.getCurrentGainIndex()).isEqualTo(TEST_GAIN_INDEX); 405 } 406 407 @Test setCurrentGainIndex_checksNewGainIsAboveMin()408 public void setCurrentGainIndex_checksNewGainIsAboveMin() { 409 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 410 411 IllegalArgumentException thrown = expectThrows(IllegalArgumentException.class, 412 () -> carVolumeGroup.setCurrentGainIndex(MIN_GAIN_INDEX - 1)); 413 assertThat(thrown).hasMessageThat() 414 .contains("Gain out of range (" + MIN_GAIN + ":" + MAX_GAIN + ")"); 415 } 416 417 @Test setCurrentGainIndex_checksNewGainIsBelowMax()418 public void setCurrentGainIndex_checksNewGainIsBelowMax() { 419 CarVolumeGroup carVolumeGroup = testVolumeGroupSetup(); 420 421 IllegalArgumentException thrown = expectThrows(IllegalArgumentException.class, 422 () -> carVolumeGroup.setCurrentGainIndex(MAX_GAIN_INDEX + 1)); 423 assertThat(thrown).hasMessageThat() 424 .contains("Gain out of range (" + MIN_GAIN + ":" + MAX_GAIN + ")"); 425 } 426 427 @Test setCurrentGainIndex_setsCurrentGainIndexForUser()428 public void setCurrentGainIndex_setsCurrentGainIndexForUser() { 429 CarAudioSettings settings = new SettingsBuilder(0, 0) 430 .setGainIndexForUser(TEST_USER_11) 431 .build(); 432 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithNavigationBound(settings, false); 433 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_11); 434 435 carVolumeGroup.setCurrentGainIndex(MIN_GAIN); 436 437 verify(settings).storeVolumeGainIndexForUser(TEST_USER_11, 0, 0, MIN_GAIN); 438 } 439 440 @Test setCurrentGainIndex_setsCurrentGainIndexForDefaultUser()441 public void setCurrentGainIndex_setsCurrentGainIndexForDefaultUser() { 442 CarAudioSettings settings = new SettingsBuilder(0, 0) 443 .setGainIndexForUser(UserHandle.USER_CURRENT) 444 .build(); 445 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithNavigationBound(settings, false); 446 447 carVolumeGroup.setCurrentGainIndex(MIN_GAIN); 448 449 verify(settings) 450 .storeVolumeGainIndexForUser(UserHandle.USER_CURRENT, 0, 0, MIN_GAIN); 451 } 452 453 @Test loadVolumesSettingsForUser_withMutedState_loadsMuteStateForUser()454 public void loadVolumesSettingsForUser_withMutedState_loadsMuteStateForUser() { 455 CarVolumeGroup carVolumeGroup = getVolumeGroupWithMuteAndNavBound(true, true, true); 456 457 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 458 459 assertThat(carVolumeGroup.isMuted()).isTrue(); 460 } 461 462 @Test loadVolumesSettingsForUser_withDisabledUseVolumeGroupMute_doesNotLoadMute()463 public void loadVolumesSettingsForUser_withDisabledUseVolumeGroupMute_doesNotLoadMute() { 464 CarVolumeGroup carVolumeGroup = getVolumeGroupWithMuteAndNavBound(true, true, false); 465 466 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 467 468 assertThat(carVolumeGroup.isMuted()).isFalse(); 469 } 470 471 @Test loadVolumesSettingsForUser_withUnMutedState_loadsMuteStateForUser()472 public void loadVolumesSettingsForUser_withUnMutedState_loadsMuteStateForUser() { 473 CarVolumeGroup carVolumeGroup = getVolumeGroupWithMuteAndNavBound(false, true, true); 474 475 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 476 477 assertThat(carVolumeGroup.isMuted()).isFalse(); 478 } 479 480 @Test loadVolumesSettingsForUser_withMutedStateAndNoPersist_returnsDefaultMuteState()481 public void loadVolumesSettingsForUser_withMutedStateAndNoPersist_returnsDefaultMuteState() { 482 CarVolumeGroup carVolumeGroup = getVolumeGroupWithMuteAndNavBound(true, false, true); 483 484 carVolumeGroup.loadVolumesSettingsForUser(TEST_USER_10); 485 486 assertThat(carVolumeGroup.isMuted()).isFalse(); 487 } 488 489 @Test hasCriticalAudioContexts_withoutCriticalContexts_returnsFalse()490 public void hasCriticalAudioContexts_withoutCriticalContexts_returnsFalse() { 491 CarVolumeGroup carVolumeGroup = getCarVolumeGroupWithMusicBound(); 492 493 assertThat(carVolumeGroup.hasCriticalAudioContexts()).isFalse(); 494 } 495 496 @Test hasCriticalAudioContexts_withCriticalContexts_returnsTrue()497 public void hasCriticalAudioContexts_withCriticalContexts_returnsTrue() { 498 CarVolumeGroup carVolumeGroup = getBuilder() 499 .setDeviceInfoForContext(CarAudioContext.EMERGENCY, mMediaDeviceInfo) 500 .build(); 501 502 assertThat(carVolumeGroup.hasCriticalAudioContexts()).isTrue(); 503 } 504 getCarVolumeGroupWithMusicBound()505 private CarVolumeGroup getCarVolumeGroupWithMusicBound() { 506 return getBuilder() 507 .setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo) 508 .build(); 509 } 510 getCarVolumeGroupWithNavigationBound(CarAudioSettings settings, boolean useCarVolumeGroupMute)511 private CarVolumeGroup getCarVolumeGroupWithNavigationBound(CarAudioSettings settings, 512 boolean useCarVolumeGroupMute) { 513 return new CarVolumeGroup.Builder(0, 0, settings, useCarVolumeGroupMute) 514 .setDeviceInfoForContext(CarAudioContext.NAVIGATION, mNavigationDeviceInfo) 515 .build(); 516 } 517 getVolumeGroupWithMuteAndNavBound(boolean isMuted, boolean persistMute, boolean useCarVolumeGroupMute)518 CarVolumeGroup getVolumeGroupWithMuteAndNavBound(boolean isMuted, boolean persistMute, 519 boolean useCarVolumeGroupMute) { 520 CarAudioSettings settings = new SettingsBuilder(0, 0) 521 .setMuteForUser10(isMuted) 522 .setIsPersistVolumeGroupEnabled(persistMute) 523 .build(); 524 return getCarVolumeGroupWithNavigationBound(settings, useCarVolumeGroupMute); 525 } 526 testVolumeGroupSetup()527 private CarVolumeGroup testVolumeGroupSetup() { 528 CarVolumeGroup.Builder builder = getBuilder(); 529 530 builder.setDeviceInfoForContext(CarAudioContext.MUSIC, mMediaDeviceInfo); 531 builder.setDeviceInfoForContext(CarAudioContext.CALL, mMediaDeviceInfo); 532 builder.setDeviceInfoForContext(CarAudioContext.CALL_RING, mMediaDeviceInfo); 533 534 builder.setDeviceInfoForContext(CarAudioContext.NAVIGATION, mNavigationDeviceInfo); 535 builder.setDeviceInfoForContext(CarAudioContext.ALARM, mNavigationDeviceInfo); 536 builder.setDeviceInfoForContext(CarAudioContext.NOTIFICATION, mNavigationDeviceInfo); 537 538 return builder.build(); 539 } 540 getBuilder()541 CarVolumeGroup.Builder getBuilder() { 542 return new CarVolumeGroup.Builder(ZONE_ID, GROUP_ID, mSettingsMock, true); 543 } 544 545 private static final class SettingsBuilder { 546 private final SparseIntArray mStoredGainIndexes = new SparseIntArray(); 547 private final SparseBooleanArray mStoreMuteStates = new SparseBooleanArray(); 548 private final int mZoneId; 549 private final int mGroupId; 550 551 private boolean mPersistMute; 552 SettingsBuilder(int zoneId, int groupId)553 SettingsBuilder(int zoneId, int groupId) { 554 mZoneId = zoneId; 555 mGroupId = groupId; 556 } 557 setGainIndexForUser(@serIdInt int userId)558 SettingsBuilder setGainIndexForUser(@UserIdInt int userId) { 559 mStoredGainIndexes.put(userId, TEST_GAIN_INDEX); 560 return this; 561 } 562 setMuteForUser10(boolean mute)563 SettingsBuilder setMuteForUser10(boolean mute) { 564 mStoreMuteStates.put(CarVolumeGroupUnitTest.TEST_USER_10, mute); 565 return this; 566 } 567 setIsPersistVolumeGroupEnabled(boolean persistMute)568 SettingsBuilder setIsPersistVolumeGroupEnabled(boolean persistMute) { 569 mPersistMute = persistMute; 570 return this; 571 } 572 build()573 CarAudioSettings build() { 574 CarAudioSettings settingsMock = Mockito.mock(CarAudioSettings.class); 575 for (int storeIndex = 0; storeIndex < mStoredGainIndexes.size(); storeIndex++) { 576 int gainUserId = mStoredGainIndexes.keyAt(storeIndex); 577 when(settingsMock 578 .getStoredVolumeGainIndexForUser(gainUserId, mZoneId, 579 mGroupId)).thenReturn( 580 mStoredGainIndexes.get(gainUserId, DEFAULT_GAIN)); 581 } 582 for (int muteIndex = 0; muteIndex < mStoreMuteStates.size(); muteIndex++) { 583 int muteUserId = mStoreMuteStates.keyAt(muteIndex); 584 when(settingsMock.getVolumeGroupMuteForUser(muteUserId, mZoneId, mGroupId)) 585 .thenReturn(mStoreMuteStates.get(muteUserId, false)); 586 when(settingsMock.isPersistVolumeGroupMuteEnabled(muteUserId)) 587 .thenReturn(mPersistMute); 588 } 589 return settingsMock; 590 } 591 } 592 593 private static final class InfoBuilder { 594 private final String mAddress; 595 596 private int mStepValue = STEP_VALUE; 597 private int mDefaultGain = DEFAULT_GAIN; 598 private int mMinGain = MIN_GAIN; 599 private int mMaxGain = MAX_GAIN; 600 InfoBuilder(String address)601 InfoBuilder(String address) { 602 mAddress = address; 603 } 604 setStepValue(int stepValue)605 InfoBuilder setStepValue(int stepValue) { 606 mStepValue = stepValue; 607 return this; 608 } 609 setDefaultGain(int defaultGain)610 InfoBuilder setDefaultGain(int defaultGain) { 611 mDefaultGain = defaultGain; 612 return this; 613 } 614 setMinGain(int minGain)615 InfoBuilder setMinGain(int minGain) { 616 mMinGain = minGain; 617 return this; 618 } 619 setMaxGain(int maxGain)620 InfoBuilder setMaxGain(int maxGain) { 621 mMaxGain = maxGain; 622 return this; 623 } 624 build()625 CarAudioDeviceInfo build() { 626 CarAudioDeviceInfo infoMock = Mockito.mock(CarAudioDeviceInfo.class); 627 when(infoMock.getStepValue()).thenReturn(mStepValue); 628 when(infoMock.getDefaultGain()).thenReturn(mDefaultGain); 629 when(infoMock.getMaxGain()).thenReturn(mMaxGain); 630 when(infoMock.getMinGain()).thenReturn(mMinGain); 631 when(infoMock.getAddress()).thenReturn(mAddress); 632 return infoMock; 633 } 634 } 635 } 636