1 /* 2 * Copyright (C) 2022 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.oem; 18 19 import static android.car.feature.Flags.FLAG_CAR_AUDIO_DYNAMIC_DEVICES; 20 import static android.car.oem.CarAudioFeaturesInfo.AUDIO_FEATURE_ISOLATED_DEVICE_FOCUS; 21 import static android.car.oem.CarAudioFeaturesInfo.AUDIO_FEATURE_FADE_MANAGER_CONFIGS; 22 import static android.media.AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE; 23 import static android.media.AudioAttributes.USAGE_ASSISTANT; 24 import static android.media.AudioAttributes.USAGE_MEDIA; 25 import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION; 26 27 import static org.junit.Assert.assertThrows; 28 29 import android.car.media.CarAudioManager; 30 import android.car.media.CarVolumeGroupInfo; 31 import android.car.test.AbstractExpectableTestCase; 32 import android.os.Parcel; 33 import android.platform.test.flag.junit.SetFlagsRule; 34 35 import org.jetbrains.annotations.NotNull; 36 import org.junit.Rule; 37 import org.junit.Test; 38 39 import java.util.ArrayList; 40 import java.util.List; 41 42 public final class OemCarAudioFocusEvaluationRequestUnitTest extends AbstractExpectableTestCase { 43 44 private static final AudioFocusEntry TEST_MEDIA_AUDIO_FOCUS_ENTRY = 45 OemFocusUtils.getAudioFocusEntry(USAGE_MEDIA); 46 private static final AudioFocusEntry TEST_CALL_FOCUS_FOCUS_ENTRY = 47 OemFocusUtils.getAudioFocusEntry(USAGE_VOICE_COMMUNICATION); 48 private static final AudioFocusEntry TEST_NAV_AUDIO_FOCUS_ENTRY = 49 OemFocusUtils.getAudioFocusEntry(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE); 50 private static final AudioFocusEntry TEST_ASSISTANT_AUDIO_FOCUS_ENTRY = 51 OemFocusUtils.getAudioFocusEntry(USAGE_ASSISTANT); 52 private static final int TEST_PARCEL_FLAGS = 0; 53 private static final int TEST_VOLUME_GROUP_ID = 2; 54 private static final int TEST_ZONE_ID = CarAudioManager.PRIMARY_AUDIO_ZONE + 1; 55 private static final String TEST_GROUP_NAME = "media"; 56 private static final int TEST_MAX_GAIN_INDEX = 9_000; 57 private static final int TEST_MIN_GAIN_INDEX = 0; 58 private static final int TEST_MAX_ACTIVATION_GAIN_INDEX = 8_000; 59 private static final int TEST_MIN_ACTIVATION_GAIN_INDEX = 1_000; 60 private static final CarVolumeGroupInfo TEST_MUTED_VOLUME_GROUP = 61 new CarVolumeGroupInfo.Builder(TEST_GROUP_NAME, CarAudioManager.PRIMARY_AUDIO_ZONE, 62 TEST_VOLUME_GROUP_ID).setMaxVolumeGainIndex(TEST_MAX_GAIN_INDEX) 63 .setMinVolumeGainIndex(TEST_MIN_GAIN_INDEX) 64 .setMaxActivationVolumeGainIndex(TEST_MAX_ACTIVATION_GAIN_INDEX) 65 .setMinActivationVolumeGainIndex(TEST_MIN_ACTIVATION_GAIN_INDEX).build(); 66 private static final CarVolumeGroupInfo TEST_MUTED_VOLUME_GROUP_2 = 67 new CarVolumeGroupInfo.Builder(TEST_GROUP_NAME, TEST_ZONE_ID, 68 TEST_VOLUME_GROUP_ID).setMaxVolumeGainIndex(TEST_MAX_GAIN_INDEX) 69 .setMinVolumeGainIndex(TEST_MIN_GAIN_INDEX) 70 .setMaxActivationVolumeGainIndex(TEST_MAX_ACTIVATION_GAIN_INDEX) 71 .setMinActivationVolumeGainIndex(TEST_MIN_ACTIVATION_GAIN_INDEX).build(); 72 73 @Rule 74 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 75 76 @Test build()77 public void build() { 78 OemCarAudioFocusEvaluationRequest request = new OemCarAudioFocusEvaluationRequest.Builder( 79 List.of(TEST_MUTED_VOLUME_GROUP), List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), 80 List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), CarAudioManager.PRIMARY_AUDIO_ZONE) 81 .setAudioFocusRequest(TEST_CALL_FOCUS_FOCUS_ENTRY).build(); 82 83 expectWithMessage("Audio focus request").that(request.getAudioFocusRequest()) 84 .isEqualTo(TEST_CALL_FOCUS_FOCUS_ENTRY); 85 expectWithMessage("Audio focus losers").that(request.getFocusLosers()) 86 .containsExactly(TEST_NAV_AUDIO_FOCUS_ENTRY); 87 expectWithMessage("Audio focus holders").that(request.getFocusHolders()) 88 .containsExactly(TEST_MEDIA_AUDIO_FOCUS_ENTRY); 89 expectWithMessage("Muted audio volume groups").that(request.getMutedVolumeGroups()) 90 .containsExactly(TEST_MUTED_VOLUME_GROUP); 91 expectWithMessage("Request audio zone").that(request.getAudioZoneId()) 92 .isEqualTo(CarAudioManager.PRIMARY_AUDIO_ZONE); 93 } 94 95 @Test writeToParcel()96 public void writeToParcel() { 97 Parcel parcel = Parcel.obtain(); 98 99 OemCarAudioFocusEvaluationRequest request = createRequestAndWriteToParcel(parcel); 100 101 expectWithMessage("Car audio focus evaluation request from parcel") 102 .that(new OemCarAudioFocusEvaluationRequest(parcel)).isEqualTo(request); 103 } 104 105 @Test createFromParcel()106 public void createFromParcel() { 107 Parcel parcel = Parcel.obtain(); 108 OemCarAudioFocusEvaluationRequest request = createRequestAndWriteToParcel(parcel); 109 110 expectWithMessage("Car audio focus evaluation request created from parcel") 111 .that(OemCarAudioFocusEvaluationRequest.CREATOR.createFromParcel(parcel)) 112 .isEqualTo(request); 113 } 114 115 @NotNull createRequestAndWriteToParcel(Parcel parcel)116 private OemCarAudioFocusEvaluationRequest createRequestAndWriteToParcel(Parcel parcel) { 117 OemCarAudioFocusEvaluationRequest request = new OemCarAudioFocusEvaluationRequest.Builder( 118 List.of(TEST_MUTED_VOLUME_GROUP), List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), 119 List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), CarAudioManager.PRIMARY_AUDIO_ZONE) 120 .setAudioFocusRequest(TEST_CALL_FOCUS_FOCUS_ENTRY).build(); 121 request.writeToParcel(parcel, TEST_PARCEL_FLAGS); 122 parcel.setDataPosition(/* pos= */ 0); 123 return request; 124 } 125 126 @Test builder_withReuse_fails()127 public void builder_withReuse_fails() { 128 OemCarAudioFocusEvaluationRequest.Builder builder = 129 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 130 List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), 131 CarAudioManager.PRIMARY_AUDIO_ZONE) 132 .setAudioFocusRequest(TEST_CALL_FOCUS_FOCUS_ENTRY); 133 builder.build(); 134 135 IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> 136 builder.build() 137 ); 138 139 expectWithMessage("Reuse builder exception") 140 .that(thrown).hasMessageThat().contains("should not be reused"); 141 } 142 143 @Test builder_withNullFocusRequest_succeeds()144 public void builder_withNullFocusRequest_succeeds() { 145 OemCarAudioFocusEvaluationRequest request = 146 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 147 List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), 148 List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), CarAudioManager.PRIMARY_AUDIO_ZONE) 149 .build(); 150 151 OemCarAudioFocusEvaluationRequest nullFocusRequest = 152 new OemCarAudioFocusEvaluationRequest(null, List.of(TEST_MUTED_VOLUME_GROUP), 153 List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), 154 /* carAudioFeaturesInfo= */ null, CarAudioManager.PRIMARY_AUDIO_ZONE); 155 156 expectWithMessage("Request with null audio focus request") 157 .that(nullFocusRequest).isEqualTo(request); 158 expectWithMessage("Audio focus entry request") 159 .that(request.getAudioFocusRequest()).isNull(); 160 } 161 162 @Test setAudioZoneId_succeeds()163 public void setAudioZoneId_succeeds() { 164 OemCarAudioFocusEvaluationRequest request = 165 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 166 List.of(TEST_MEDIA_AUDIO_FOCUS_ENTRY), List.of(TEST_NAV_AUDIO_FOCUS_ENTRY), 167 CarAudioManager.PRIMARY_AUDIO_ZONE).setAudioZoneId(TEST_ZONE_ID).build(); 168 169 expectWithMessage("Request zone id").that(request.getAudioZoneId()) 170 .isEqualTo(TEST_ZONE_ID); 171 } 172 173 @Test setFocusHolders()174 public void setFocusHolders() { 175 OemCarAudioFocusEvaluationRequest request = 176 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 177 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 178 .setFocusHolders(List.of(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY)).build(); 179 180 expectWithMessage("Focus holders").that(request.getFocusHolders()) 181 .contains(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY); 182 } 183 184 @Test setFocusHolders_withNullHolders_fails()185 public void setFocusHolders_withNullHolders_fails() { 186 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 187 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 188 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 189 .setFocusHolders(null) 190 ); 191 192 expectWithMessage("Null holders exception") 193 .that(thrown).hasMessageThat().contains("Focus holders"); 194 } 195 196 @Test addFocusHolders()197 public void addFocusHolders() { 198 OemCarAudioFocusEvaluationRequest request = 199 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 200 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 201 .addFocusHolders(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY).build(); 202 203 expectWithMessage("Focus holder").that(request.getFocusHolders()) 204 .containsExactly(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY); 205 } 206 207 @Test addFocusHolders_withNullHolder_fails()208 public void addFocusHolders_withNullHolder_fails() { 209 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 210 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 211 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 212 .addFocusHolders(null) 213 ); 214 215 expectWithMessage("Null holder exception") 216 .that(thrown).hasMessageThat().contains("Focus holder"); 217 } 218 219 @Test setFocusLosers()220 public void setFocusLosers() { 221 OemCarAudioFocusEvaluationRequest request = 222 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 223 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 224 .setFocusLosers(List.of(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY)).build(); 225 226 expectWithMessage("Focus losers").that(request.getFocusLosers()) 227 .containsExactly(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY); 228 } 229 230 @Test setFocusLosers_withNullLosers_fails()231 public void setFocusLosers_withNullLosers_fails() { 232 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 233 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 234 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 235 .setFocusLosers(null) 236 ); 237 238 expectWithMessage("Null losers exception") 239 .that(thrown).hasMessageThat().contains("Focus loser"); 240 } 241 242 @Test addFocusLosers()243 public void addFocusLosers() { 244 OemCarAudioFocusEvaluationRequest request = 245 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 246 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 247 .addFocusLosers(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY).build(); 248 249 expectWithMessage("Focus loser").that(request.getFocusLosers()) 250 .containsExactly(TEST_ASSISTANT_AUDIO_FOCUS_ENTRY); 251 } 252 253 @Test addFocusLosers_withNullLosers_fails()254 public void addFocusLosers_withNullLosers_fails() { 255 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 256 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 257 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 258 .addFocusLosers(null) 259 ); 260 261 expectWithMessage("Null loser exception") 262 .that(thrown).hasMessageThat().contains("Focus loser"); 263 } 264 265 @Test setMutedVolumeGroups()266 public void setMutedVolumeGroups() { 267 OemCarAudioFocusEvaluationRequest request = 268 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 269 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 270 .setMutedVolumeGroups(List.of(TEST_MUTED_VOLUME_GROUP_2)).build(); 271 272 expectWithMessage("Muted volume groups").that(request.getMutedVolumeGroups()) 273 .containsExactly(TEST_MUTED_VOLUME_GROUP_2); 274 } 275 276 @Test setMutedVolumeGroups_withNullGroups_fails()277 public void setMutedVolumeGroups_withNullGroups_fails() { 278 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 279 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 280 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 281 .setMutedVolumeGroups(null) 282 ); 283 284 expectWithMessage("Null muted volume groups exception") 285 .that(thrown).hasMessageThat().contains("Muted volume groups"); 286 } 287 288 @Test addMutedVolumeGroups()289 public void addMutedVolumeGroups() { 290 OemCarAudioFocusEvaluationRequest request = 291 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 292 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 293 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2).build(); 294 295 expectWithMessage("Muted volume group").that(request.getMutedVolumeGroups()) 296 .containsExactly(TEST_MUTED_VOLUME_GROUP_2); 297 } 298 299 @Test addMutedVolumeGroups_withNullGroups_fails()300 public void addMutedVolumeGroups_withNullGroups_fails() { 301 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 302 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 303 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 304 .addMutedVolumeGroups(null) 305 ); 306 307 expectWithMessage("Null muted volume group exception") 308 .that(thrown).hasMessageThat().contains("Muted volume group"); 309 } 310 311 312 @Test setAudioFocusRequest_withNullGroups_fails()313 public void setAudioFocusRequest_withNullGroups_fails() { 314 IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> 315 new OemCarAudioFocusEvaluationRequest.Builder(List.of(TEST_MUTED_VOLUME_GROUP), 316 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 317 .setAudioFocusRequest(null) 318 ); 319 320 expectWithMessage("Null audio focus request exception") 321 .that(thrown).hasMessageThat().contains("Audio focus request"); 322 } 323 324 @Test getAudioFeaturesInfo()325 public void getAudioFeaturesInfo() { 326 mSetFlagsRule.enableFlags(FLAG_CAR_AUDIO_DYNAMIC_DEVICES); 327 CarAudioFeaturesInfo featureInfo = new CarAudioFeaturesInfo.Builder( 328 AUDIO_FEATURE_ISOLATED_DEVICE_FOCUS).addAudioFeature( 329 AUDIO_FEATURE_FADE_MANAGER_CONFIGS).build(); 330 OemCarAudioFocusEvaluationRequest request = 331 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 332 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 333 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2) 334 .setAudioFeaturesInfo(featureInfo).build(); 335 336 CarAudioFeaturesInfo requestFeatureInfo = request.getAudioFeaturesInfo(); 337 338 expectWithMessage("Existing audio feature info").that(requestFeatureInfo).isNotNull(); 339 expectWithMessage("Audio feature info").that(requestFeatureInfo).isEqualTo(featureInfo); 340 expectWithMessage("Isolated audio focus feature").that(requestFeatureInfo 341 .isAudioFeatureEnabled(AUDIO_FEATURE_ISOLATED_DEVICE_FOCUS)).isTrue(); 342 expectWithMessage("Fade manager configuration audio feature").that(requestFeatureInfo 343 .isAudioFeatureEnabled(AUDIO_FEATURE_FADE_MANAGER_CONFIGS)) 344 .isTrue(); 345 } 346 347 @Test equals_withSameFeatureInfo()348 public void equals_withSameFeatureInfo() { 349 mSetFlagsRule.enableFlags(FLAG_CAR_AUDIO_DYNAMIC_DEVICES); 350 CarAudioFeaturesInfo featureInfo = new CarAudioFeaturesInfo.Builder( 351 AUDIO_FEATURE_ISOLATED_DEVICE_FOCUS).build(); 352 OemCarAudioFocusEvaluationRequest requestOne = 353 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 354 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 355 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2) 356 .setAudioFeaturesInfo(featureInfo).build(); 357 OemCarAudioFocusEvaluationRequest requestTwo = 358 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 359 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 360 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2) 361 .setAudioFeaturesInfo(featureInfo).build(); 362 363 expectWithMessage("Car audio focus eval requests").that(requestOne).isEqualTo(requestTwo); 364 } 365 366 @Test equals_withDifferentFeatureInfo()367 public void equals_withDifferentFeatureInfo() { 368 mSetFlagsRule.enableFlags(FLAG_CAR_AUDIO_DYNAMIC_DEVICES); 369 CarAudioFeaturesInfo featureInfoOne = new CarAudioFeaturesInfo.Builder( 370 AUDIO_FEATURE_ISOLATED_DEVICE_FOCUS).build(); 371 CarAudioFeaturesInfo featureInfoTwo = new CarAudioFeaturesInfo.Builder( 372 AUDIO_FEATURE_FADE_MANAGER_CONFIGS).build(); 373 OemCarAudioFocusEvaluationRequest requestOne = 374 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 375 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 376 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2) 377 .setAudioFeaturesInfo(featureInfoOne).build(); 378 OemCarAudioFocusEvaluationRequest requestTwo = 379 new OemCarAudioFocusEvaluationRequest.Builder(new ArrayList<>(), 380 new ArrayList<>(), new ArrayList<>(), CarAudioManager.PRIMARY_AUDIO_ZONE) 381 .addMutedVolumeGroups(TEST_MUTED_VOLUME_GROUP_2) 382 .setAudioFeaturesInfo(featureInfoTwo).build(); 383 384 expectWithMessage("Car audio focus eval requests with different feature info") 385 .that(requestOne).isNotEqualTo(requestTwo); 386 } 387 } 388