• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.audio;
18 
19 import static android.media.AudioAttributes.USAGE_ALARM;
20 import static android.media.AudioAttributes.USAGE_ANNOUNCEMENT;
21 import static android.media.AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
22 import static android.media.AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
23 import static android.media.AudioAttributes.USAGE_ASSISTANT;
24 import static android.media.AudioAttributes.USAGE_CALL_ASSISTANT;
25 import static android.media.AudioAttributes.USAGE_EMERGENCY;
26 import static android.media.AudioAttributes.USAGE_GAME;
27 import static android.media.AudioAttributes.USAGE_MEDIA;
28 import static android.media.AudioAttributes.USAGE_NOTIFICATION;
29 import static android.media.AudioAttributes.USAGE_NOTIFICATION_EVENT;
30 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
31 import static android.media.AudioAttributes.USAGE_SAFETY;
32 import static android.media.AudioAttributes.USAGE_UNKNOWN;
33 import static android.media.AudioAttributes.USAGE_VEHICLE_STATUS;
34 import static android.media.AudioAttributes.USAGE_VIRTUAL_SOURCE;
35 import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION;
36 
37 import static com.android.car.audio.CarAudioContext.isCriticalAudioAudioAttribute;
38 import static com.android.car.audio.CarAudioContext.isNotificationAudioAttribute;
39 import static com.android.car.audio.CarAudioContext.isRingerOrCallAudioAttribute;
40 import static com.android.car.audio.CarAudioTestUtils.TEST_GAME_USAGE_ATTRIBUTE;
41 import static com.android.car.audio.CarAudioTestUtils.TEST_ALARM_ATTRIBUTE;
42 import static com.android.car.audio.CarAudioTestUtils.TEST_ANNOUNCEMENT_ATTRIBUTE;
43 import static com.android.car.audio.CarAudioTestUtils.TEST_ASSISTANT_ATTRIBUTE;
44 import static com.android.car.audio.CarAudioTestUtils.TEST_CALL_ATTRIBUTE;
45 import static com.android.car.audio.CarAudioTestUtils.TEST_CAR_AUDIO_CONTEXT;
46 import static com.android.car.audio.CarAudioTestUtils.TEST_EMERGENCY_ATTRIBUTE;
47 import static com.android.car.audio.CarAudioTestUtils.TEST_INVALID_ATTRIBUTE;
48 import static com.android.car.audio.CarAudioTestUtils.TEST_MEDIA_ATTRIBUTE;
49 import static com.android.car.audio.CarAudioTestUtils.TEST_NAVIGATION_ATTRIBUTE;
50 import static com.android.car.audio.CarAudioTestUtils.TEST_NOTIFICATION_ATTRIBUTE;
51 import static com.android.car.audio.CarAudioTestUtils.TEST_NOTIFICATION_EVENT_ATTRIBUTE;
52 import static com.android.car.audio.CarAudioTestUtils.TEST_RINGER_ATTRIBUTE;
53 import static com.android.car.audio.CarAudioTestUtils.TEST_SAFETY_ATTRIBUTE;
54 import static com.android.car.audio.CarAudioTestUtils.TEST_SYSTEM_ATTRIBUTE;
55 import static com.android.car.audio.CarAudioTestUtils.TEST_VEHICLE_ATTRIBUTE;
56 import static com.android.car.audio.CarAudioTestUtils.TEST_UNKNOWN_USAGE_ATTRIBUTE;
57 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
58 
59 import static org.junit.Assert.assertThrows;
60 import static org.mockito.ArgumentMatchers.eq;
61 
62 import android.car.builtin.media.AudioManagerHelper;
63 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
64 import android.media.AudioAttributes;
65 import android.util.ArraySet;
66 
67 import androidx.test.ext.junit.runners.AndroidJUnit4;
68 
69 import com.android.car.audio.CarAudioContext.AudioContext;
70 import com.android.car.internal.util.DebugUtils;
71 
72 import org.junit.Before;
73 import org.junit.Test;
74 import org.junit.runner.RunWith;
75 
76 import java.util.ArrayList;
77 import java.util.Arrays;
78 import java.util.Collections;
79 import java.util.List;
80 import java.util.Set;
81 import java.util.stream.Collectors;
82 
83 @RunWith(AndroidJUnit4.class)
84 public class CarAudioContextTest extends AbstractExtendedMockitoTestCase {
85 
86     private static final String TAG = CarAudioContextTest.class.getSimpleName();
87 
88     private static final int INVALID_CONTEXT_ID = 0;
89     private static final int INVALID_CONTEXT = -5;
90 
91     public static final @CarAudioContext.AudioContext int TEST_MEDIA_CONTEXT =
92             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_MEDIA_ATTRIBUTE);
93     public static final @CarAudioContext.AudioContext int TEST_ALARM_CONTEXT =
94             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_ALARM_ATTRIBUTE);
95     public static final @CarAudioContext.AudioContext int TEST_CALL_CONTEXT =
96             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_CALL_ATTRIBUTE);
97     public static final @CarAudioContext.AudioContext int TEST_CALL_RING_CONTEXT =
98             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_RINGER_ATTRIBUTE);
99     public static final @CarAudioContext.AudioContext int TEST_EMERGENCY_CONTEXT =
100             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_EMERGENCY_ATTRIBUTE);
101     public static final @CarAudioContext.AudioContext int TEST_NAVIGATION_CONTEXT =
102             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_NAVIGATION_ATTRIBUTE);
103     public static final @CarAudioContext.AudioContext int TEST_NOTIFICATION_CONTEXT =
104             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_NOTIFICATION_ATTRIBUTE);
105     public static final @CarAudioContext.AudioContext int TEST_ANNOUNCEMENT_CONTEXT =
106             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_ANNOUNCEMENT_ATTRIBUTE);
107     public static final @CarAudioContext.AudioContext int TEST_SAFETY_CONTEXT =
108             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_SAFETY_ATTRIBUTE);
109     public static final @CarAudioContext.AudioContext int TEST_SYSTEM_SOUND_CONTEXT =
110             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_SYSTEM_ATTRIBUTE);
111     public static final @CarAudioContext.AudioContext int TEST_VEHICLE_STATUS_CONTEXT =
112             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_VEHICLE_ATTRIBUTE);
113     public static final @CarAudioContext.AudioContext int TEST_ASSISTANT_CONTEXT =
114             TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(TEST_ASSISTANT_ATTRIBUTE);
115 
116     @Override
onSessionBuilder(CustomMockitoSessionBuilder session)117     protected void onSessionBuilder(CustomMockitoSessionBuilder session) {
118         session
119                 .spyStatic(CoreAudioHelper.class)
120                 .spyStatic(AudioManagerWrapper.class);
121     }
122 
setupMock()123     void setupMock() {
124         doReturn(CoreAudioRoutingUtils.getProductStrategies())
125                 .when(AudioManagerWrapper::getAudioProductStrategies);
126         doReturn(CoreAudioRoutingUtils.getVolumeGroups())
127                 .when(AudioManagerWrapper::getAudioVolumeGroups);
128 
129         doReturn(CoreAudioRoutingUtils.MUSIC_STRATEGY_ID)
130                 .when(() -> CoreAudioHelper.getStrategyForAudioAttributes(
131                         eq(CoreAudioRoutingUtils.MUSIC_ATTRIBUTES)));
132         doReturn(CoreAudioRoutingUtils.NAV_STRATEGY_ID)
133                 .when(() -> CoreAudioHelper.getStrategyForAudioAttributes(
134                         eq(CoreAudioRoutingUtils.NAV_ATTRIBUTES)));
135         doReturn(CoreAudioRoutingUtils.OEM_STRATEGY_ID)
136                 .when(() -> CoreAudioHelper.getStrategyForAudioAttributes(
137                         eq(CoreAudioRoutingUtils.OEM_ATTRIBUTES)));
138         doReturn(CoreAudioHelper.INVALID_STRATEGY)
139                 .when(() -> CoreAudioHelper.getStrategyForAudioAttributes(
140                         eq(CoreAudioRoutingUtils.UNSUPPORTED_ATTRIBUTES)));
141     }
142 
143     @Before
setUp()144     public void setUp() {
145         setupMock();
146     }
147 
CarAudioContextTest()148     public CarAudioContextTest() {
149         super(CarAudioContextTest.TAG);
150     }
151 
152     @Test
getContextForAudioAttribute_usingCoreRouting()153     public void getContextForAudioAttribute_usingCoreRouting() {
154         CarAudioContext carAudioContextUsingCoreRouting = new CarAudioContext(
155                 CoreAudioRoutingUtils.getCarAudioContextInfos(), /* useCoreAudioRouting= */ true);
156 
157         expectWithMessage("Context for valid audio attributes")
158                 .that(carAudioContextUsingCoreRouting.getContextForAttributes(
159                         CoreAudioRoutingUtils.MUSIC_ATTRIBUTES))
160                 .isEqualTo(CoreAudioRoutingUtils.MUSIC_STRATEGY_ID);
161         expectWithMessage("Context for unsupported audio attributes")
162                 .that(carAudioContextUsingCoreRouting.getContextForAttributes(
163                         CoreAudioRoutingUtils.UNSUPPORTED_ATTRIBUTES))
164                 .isEqualTo(INVALID_CONTEXT_ID);
165     }
166 
167     @Test
isOemExtensionAudioContext_whenUsingCoreRouting()168     public void isOemExtensionAudioContext_whenUsingCoreRouting() {
169         CarAudioContext carAudioContextUsingCoreRouting = new CarAudioContext(
170                 CoreAudioRoutingUtils.getCarAudioContextInfos(), /* useCoreAudioRouting= */ true);
171 
172         expectWithMessage("Oem extension Context for music audio attributes")
173                 .that(carAudioContextUsingCoreRouting.isOemExtensionAudioContext(
174                         CoreAudioRoutingUtils.MUSIC_STRATEGY_ID))
175                 .isTrue();
176         expectWithMessage("Nav Context for USAGE_ASSISTANCE_NAVIGATION_GUIDANCE")
177                 .that(carAudioContextUsingCoreRouting.isOemExtensionAudioContext(
178                         CoreAudioRoutingUtils.NAV_STRATEGY_ID))
179                 .isFalse();
180         expectWithMessage("Oem extension Context for oem audio attributes")
181                 .that(carAudioContextUsingCoreRouting.isOemExtensionAudioContext(
182                         CoreAudioRoutingUtils.OEM_STRATEGY_ID))
183                 .isTrue();
184     }
185 
186     @Test
getContextForAudioAttributes_forAttributeWithValidUsage_returnsContext()187     public void getContextForAudioAttributes_forAttributeWithValidUsage_returnsContext() {
188         AudioAttributes attributes = new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build();
189 
190         expectWithMessage("Context for valid audio attributes usage")
191                 .that(TEST_CAR_AUDIO_CONTEXT.getContextForAttributes(attributes))
192                 .isEqualTo(TEST_MEDIA_CONTEXT);
193     }
194 
195     @Test
getContextForAudioAttributes_forAttributesWithInvalidUsage_returnsInvalidContext()196     public void getContextForAudioAttributes_forAttributesWithInvalidUsage_returnsInvalidContext() {
197         expectWithMessage("Context for invalid audio attribute")
198                 .that(TEST_CAR_AUDIO_CONTEXT.getContextForAttributes(TEST_INVALID_ATTRIBUTE))
199                 .isEqualTo(CarAudioContext.getInvalidContext());
200     }
201 
202     @Test
getAudioAttributesForContext_withValidContext_returnsAttributes()203     public void getAudioAttributesForContext_withValidContext_returnsAttributes() {
204         AudioAttributes[] attributes =
205                 TEST_CAR_AUDIO_CONTEXT.getAudioAttributesForContext(TEST_MEDIA_CONTEXT);
206         expectWithMessage("Music context's audio attributes")
207                 .that(attributes).asList().containsExactly(TEST_UNKNOWN_USAGE_ATTRIBUTE,
208                         TEST_MEDIA_ATTRIBUTE, TEST_GAME_USAGE_ATTRIBUTE);
209     }
210 
211     @Test
getAudioAttributesForContext_withInvalidContext_throws()212     public void getAudioAttributesForContext_withInvalidContext_throws() {
213         IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
214             TEST_CAR_AUDIO_CONTEXT.getAudioAttributesForContext(INVALID_CONTEXT);
215         });
216 
217         expectWithMessage("Invalid context exception").that(thrown)
218                 .hasMessageThat().contains("Car audio context " + INVALID_CONTEXT + " is invalid");
219     }
220 
221     @Test
getAudioAttributesForContext_returnsUniqueValuesForAllContexts()222     public void getAudioAttributesForContext_returnsUniqueValuesForAllContexts() {
223         Set<CarAudioContext.AudioAttributesWrapper> allUsages = new ArraySet<>();
224         for (@AudioContext int audioContext : TEST_CAR_AUDIO_CONTEXT.getAllContextsIds()) {
225             AudioAttributes[] audioAttributes =
226                     TEST_CAR_AUDIO_CONTEXT.getAudioAttributesForContext(audioContext);
227             List<CarAudioContext.AudioAttributesWrapper> attributesWrappers =
228                     Arrays.stream(audioAttributes).map(CarAudioContext.AudioAttributesWrapper::new)
229                             .collect(Collectors.toList());
230 
231             expectWithMessage("Unique audio attributes wrapper for context %s",
232                     TEST_CAR_AUDIO_CONTEXT.toString(audioContext))
233                     .that(allUsages.addAll(attributesWrappers)).isTrue();
234         }
235     }
236 
237     @Test
getUniqueContextsForAudioAttribute_withEmptyArray_returnsEmptySet()238     public void getUniqueContextsForAudioAttribute_withEmptyArray_returnsEmptySet() {
239         Set<Integer> result =
240                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(new ArrayList<>());
241 
242         expectWithMessage("Empty unique context list").that(result).isEmpty();
243     }
244 
245     @Test
getUniqueContextsForAudioAttribute_withInvalidElement_returnsEmptySet()246     public void getUniqueContextsForAudioAttribute_withInvalidElement_returnsEmptySet() {
247         Set<Integer> result =
248                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(
249                         new ArrayList<>(TEST_CAR_AUDIO_CONTEXT
250                                 .getContextForAudioAttribute(CarAudioContext
251                                         .getAudioAttributeFromUsage(AudioManagerHelper
252                                                 .getUsageVirtualSource()))));
253 
254         expectWithMessage("Empty unique context list for invalid context")
255                 .that(result).isEmpty();
256     }
257 
258     @Test
getUniqueContextsForAudioAttribute_withNullArray_fails()259     public void getUniqueContextsForAudioAttribute_withNullArray_fails() {
260         NullPointerException thrown = assertThrows(NullPointerException.class, () -> {
261             TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(null);
262         });
263 
264         expectWithMessage("Unique contexts conversion exception")
265                 .that(thrown).hasMessageThat().contains("can not be null");
266     }
267 
268     @Test
getUniqueContextsForAudioAttributes_withMultipleAttributes_filtersDupContexts()269     public void getUniqueContextsForAudioAttributes_withMultipleAttributes_filtersDupContexts() {
270         List<AudioAttributes> audioAttributes = new ArrayList<>(2);
271         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_GAME));
272         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_MEDIA));
273 
274         Set<Integer> result = TEST_CAR_AUDIO_CONTEXT
275                 .getUniqueContextsForAudioAttributes(audioAttributes);
276 
277         expectWithMessage("Media and Game audio attribute's context")
278                 .that(result).containsExactly(TEST_MEDIA_CONTEXT);
279     }
280 
281     @Test
getUniqueContextsForAudioAttributes_withDiffAttributes_returnsAllUniqueContexts()282     public void getUniqueContextsForAudioAttributes_withDiffAttributes_returnsAllUniqueContexts() {
283         List<AudioAttributes> audioAttributes = new ArrayList<>(3);
284         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_MEDIA));
285         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_EMERGENCY));
286         audioAttributes.add(TEST_NAVIGATION_ATTRIBUTE);
287 
288         Set<Integer> result =
289                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(audioAttributes);
290 
291         expectWithMessage("Separate audio attribute's contexts")
292                 .that(result).containsExactly(TEST_MEDIA_CONTEXT,
293                         TEST_NAVIGATION_CONTEXT,
294                         TEST_EMERGENCY_CONTEXT);
295     }
296 
297     @Test
getUniqueAttributesHoldingFocus_withNoAttributes_returnsEmpty()298     public void getUniqueAttributesHoldingFocus_withNoAttributes_returnsEmpty() {
299         Set<Integer> contexts =
300                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(new ArrayList<>());
301 
302         expectWithMessage("Empty unique contexts set")
303                 .that(contexts).isEmpty();
304     }
305 
306     @Test
getUniqueAttributesHoldingFocus_withDuplicates_returnsSetWithNoDuplicates()307     public void getUniqueAttributesHoldingFocus_withDuplicates_returnsSetWithNoDuplicates() {
308         List<AudioAttributes> audioAttributes = new ArrayList<>(/* initialCapacity= */ 3);
309         audioAttributes.add(TEST_NOTIFICATION_ATTRIBUTE);
310         audioAttributes.add(TEST_MEDIA_ATTRIBUTE);
311         audioAttributes.add(TEST_NOTIFICATION_ATTRIBUTE);
312 
313         Set<Integer> contexts =
314                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(audioAttributes);
315 
316         expectWithMessage("Non duplicates unique contexts set")
317                 .that(contexts).containsExactly(TEST_MEDIA_CONTEXT,
318                         TEST_NOTIFICATION_CONTEXT);
319     }
320 
321     @Test
getUniqueAttributesHoldingFocus_withSystemAudioAttributes_retSystemContext()322     public void getUniqueAttributesHoldingFocus_withSystemAudioAttributes_retSystemContext() {
323         List<AudioAttributes> audioAttributes = new ArrayList<>(/* initialCapacity= */ 3);
324         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_MEDIA));
325         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_SAFETY));
326         audioAttributes.add(CarAudioContext.getAudioAttributeFromUsage(USAGE_EMERGENCY));
327 
328         Set<Integer> contexts =
329                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(audioAttributes);
330 
331         expectWithMessage("Non duplicates unique contexts set")
332                 .that(contexts).containsExactly(TEST_MEDIA_CONTEXT,
333                         TEST_SAFETY_CONTEXT,
334                         TEST_EMERGENCY_CONTEXT);
335     }
336 
337     @Test
getUniqueAttributesHoldingFocus_withInvalidAttribute_returnsEmpty()338     public void getUniqueAttributesHoldingFocus_withInvalidAttribute_returnsEmpty() {
339         List<AudioAttributes> audioAttributes = new ArrayList<>(/* initialCapacity= */ 1);
340         audioAttributes.add(CarAudioContext
341                 .getAudioAttributeFromUsage(AudioManagerHelper.getUsageVirtualSource()));
342 
343         Set<Integer> contexts =
344                 TEST_CAR_AUDIO_CONTEXT.getUniqueContextsForAudioAttributes(audioAttributes);
345 
346         expectWithMessage("Unique contexts without invalid")
347                 .that(contexts).isEmpty();
348     }
349 
350     @Test
isCriticalAudioContext_forNonCriticalContexts_returnsFalse()351     public void isCriticalAudioContext_forNonCriticalContexts_returnsFalse() {
352         expectWithMessage("Non-critical context INVALID")
353                 .that(isCriticalAudioAudioAttribute(TEST_INVALID_ATTRIBUTE)).isFalse();
354         expectWithMessage("Non-critical context MUSIC")
355                 .that(isCriticalAudioAudioAttribute(TEST_MEDIA_ATTRIBUTE)).isFalse();
356         expectWithMessage("Non-critical context NAVIGATION")
357                 .that(isCriticalAudioAudioAttribute(TEST_NAVIGATION_ATTRIBUTE)).isFalse();
358         expectWithMessage("Non-critical context VOICE_COMMAND")
359                 .that(isCriticalAudioAudioAttribute(TEST_ASSISTANT_ATTRIBUTE)).isFalse();
360         expectWithMessage("Non-critical context CALL_RING")
361                 .that(isCriticalAudioAudioAttribute(TEST_RINGER_ATTRIBUTE)).isFalse();
362         expectWithMessage("Non-critical context CALL")
363                 .that(isCriticalAudioAudioAttribute(TEST_CALL_ATTRIBUTE)).isFalse();
364         expectWithMessage("Non-critical context ALARM")
365                 .that(isCriticalAudioAudioAttribute(TEST_ALARM_ATTRIBUTE)).isFalse();
366         expectWithMessage("Non-critical context NOTIFICATION")
367                 .that(isCriticalAudioAudioAttribute(TEST_NOTIFICATION_ATTRIBUTE)).isFalse();
368         expectWithMessage("Non-critical context SYSTEM_SOUND")
369                 .that(isCriticalAudioAudioAttribute(TEST_SYSTEM_ATTRIBUTE)).isFalse();
370         expectWithMessage("Non-critical context VEHICLE_STATUS")
371                 .that(isCriticalAudioAudioAttribute(TEST_VEHICLE_ATTRIBUTE)).isFalse();
372         expectWithMessage("Non-critical context ANNOUNCEMENT")
373                 .that(isCriticalAudioAudioAttribute(TEST_ANNOUNCEMENT_ATTRIBUTE)).isFalse();
374     }
375 
376     @Test
isCriticalAudioContext_forCriticalContexts_returnsTrue()377     public void isCriticalAudioContext_forCriticalContexts_returnsTrue() {
378         expectWithMessage("Critical context EMERGENCY")
379                 .that(isCriticalAudioAudioAttribute(TEST_EMERGENCY_ATTRIBUTE)).isTrue();
380         expectWithMessage("Critical context SAFETY")
381                 .that(isCriticalAudioAudioAttribute(TEST_SAFETY_ATTRIBUTE)).isTrue();
382     }
383 
384     @Test
isNotificationAudioAttribute_forNonNotification_returnsFalse()385     public void isNotificationAudioAttribute_forNonNotification_returnsFalse() {
386         expectWithMessage("Non Notification attribute INVALID")
387                 .that(isNotificationAudioAttribute(TEST_INVALID_ATTRIBUTE)).isFalse();
388         expectWithMessage("Non notification attribute MUSIC")
389                 .that(isNotificationAudioAttribute(TEST_MEDIA_ATTRIBUTE)).isFalse();
390         expectWithMessage("Non notification attribute NAVIGATION")
391                 .that(isNotificationAudioAttribute(TEST_NAVIGATION_ATTRIBUTE)).isFalse();
392         expectWithMessage("Non notification attribute VOICE_COMMAND")
393                 .that(isNotificationAudioAttribute(TEST_ASSISTANT_ATTRIBUTE)).isFalse();
394         expectWithMessage("Non notification attribute ALARM")
395                 .that(isNotificationAudioAttribute(TEST_ALARM_ATTRIBUTE)).isFalse();
396         expectWithMessage("Non notification attribute SYSTEM_SOUND")
397                 .that(isNotificationAudioAttribute(TEST_SYSTEM_ATTRIBUTE)).isFalse();
398         expectWithMessage("Non notification attribute VEHICLE_STATUS")
399                 .that(isNotificationAudioAttribute(TEST_VEHICLE_ATTRIBUTE)).isFalse();
400         expectWithMessage("Non notification attribute ANNOUNCEMENT")
401                 .that(isNotificationAudioAttribute(TEST_ANNOUNCEMENT_ATTRIBUTE)).isFalse();
402         expectWithMessage("Non Notification attribute EMERGENCY")
403                 .that(isNotificationAudioAttribute(TEST_EMERGENCY_ATTRIBUTE)).isFalse();
404         expectWithMessage("Non Notification attribute SAFETY")
405                 .that(isNotificationAudioAttribute(TEST_SAFETY_ATTRIBUTE)).isFalse();
406     }
407 
408     @Test
isNotificationAudioAttribute_forNotification_returnsTrue()409     public void isNotificationAudioAttribute_forNotification_returnsTrue() {
410         expectWithMessage("Notification attribute NOTIFICATION")
411                 .that(isNotificationAudioAttribute(TEST_NOTIFICATION_ATTRIBUTE)).isTrue();
412         expectWithMessage("Notification attribute MUSIC")
413                 .that(isNotificationAudioAttribute(TEST_NOTIFICATION_EVENT_ATTRIBUTE)).isTrue();
414     }
415 
416     @Test
isRingerOrCallAudioAttribute_forNonCall_returnsFalse()417     public void isRingerOrCallAudioAttribute_forNonCall_returnsFalse() {
418         expectWithMessage("Non call attribute INVALID")
419                 .that(isRingerOrCallAudioAttribute(TEST_INVALID_ATTRIBUTE)).isFalse();
420         expectWithMessage("Non call attribute MUSIC")
421                 .that(isRingerOrCallAudioAttribute(TEST_MEDIA_ATTRIBUTE)).isFalse();
422         expectWithMessage("Non call attribute NAVIGATION")
423                 .that(isRingerOrCallAudioAttribute(TEST_NAVIGATION_ATTRIBUTE)).isFalse();
424         expectWithMessage("Non call attribute VOICE_COMMAND")
425                 .that(isRingerOrCallAudioAttribute(TEST_ASSISTANT_ATTRIBUTE)).isFalse();
426         expectWithMessage("Non call attribute ALARM")
427                 .that(isRingerOrCallAudioAttribute(TEST_ALARM_ATTRIBUTE)).isFalse();
428         expectWithMessage("Non call attribute SYSTEM_SOUND")
429                 .that(isRingerOrCallAudioAttribute(TEST_SYSTEM_ATTRIBUTE)).isFalse();
430         expectWithMessage("Non call attribute VEHICLE_STATUS")
431                 .that(isRingerOrCallAudioAttribute(TEST_VEHICLE_ATTRIBUTE)).isFalse();
432         expectWithMessage("Non call attribute ANNOUNCEMENT")
433                 .that(isRingerOrCallAudioAttribute(TEST_ANNOUNCEMENT_ATTRIBUTE)).isFalse();
434         expectWithMessage("Non call attribute EMERGENCY")
435                 .that(isRingerOrCallAudioAttribute(TEST_EMERGENCY_ATTRIBUTE)).isFalse();
436         expectWithMessage("Non call attribute SAFETY")
437                 .that(isRingerOrCallAudioAttribute(TEST_SAFETY_ATTRIBUTE)).isFalse();
438         expectWithMessage("Non call attribute NOTIFICATION")
439                 .that(isRingerOrCallAudioAttribute(TEST_NOTIFICATION_ATTRIBUTE)).isFalse();
440         expectWithMessage("Non call attribute NOTIFICATION_EVENT")
441                 .that(isRingerOrCallAudioAttribute(TEST_NOTIFICATION_EVENT_ATTRIBUTE)).isFalse();
442     }
443 
444     @Test
isRingerOrCallAudioAttribute_forCallOrRinger_returnsTrue()445     public void isRingerOrCallAudioAttribute_forCallOrRinger_returnsTrue() {
446         expectWithMessage("Non call attribute CALL")
447                 .that(isRingerOrCallAudioAttribute(TEST_CALL_ATTRIBUTE)).isTrue();
448         expectWithMessage("Non call attribute CALL_RING")
449                 .that(isRingerOrCallAudioAttribute(TEST_RINGER_ATTRIBUTE)).isTrue();
450     }
451 
452     @Test
getAudioAttributeWrapperFromUsage_withNonCriticalUsage_succeeds()453     public void getAudioAttributeWrapperFromUsage_withNonCriticalUsage_succeeds() {
454         CarAudioContext.AudioAttributesWrapper wrapper =
455                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_MEDIA);
456 
457         expectWithMessage("Non critical audio attributes for wrapper")
458                 .that(wrapper.getAudioAttributes()).isEqualTo(TEST_MEDIA_ATTRIBUTE);
459     }
460 
461     @Test
getAudioAttributeWrapperFromUsage_withNonCriticalUsage_toString_succeeds()462     public void getAudioAttributeWrapperFromUsage_withNonCriticalUsage_toString_succeeds() {
463         CarAudioContext.AudioAttributesWrapper wrapper =
464                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_MEDIA);
465 
466         expectWithMessage("Non critical audio attributes for wrapper string")
467                 .that(wrapper.toString()).isEqualTo(TEST_MEDIA_ATTRIBUTE.toString());
468     }
469 
470     @Test
getAudioAttributeWrapperFromUsage_withNonCriticalUsage_equals_succeeds()471     public void getAudioAttributeWrapperFromUsage_withNonCriticalUsage_equals_succeeds() {
472         CarAudioContext.AudioAttributesWrapper wrapper =
473                 new CarAudioContext.AudioAttributesWrapper(TEST_MEDIA_ATTRIBUTE);
474 
475         CarAudioContext.AudioAttributesWrapper createdWrapper =
476                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_MEDIA);
477 
478         expectWithMessage("Non critical audio attributes wrapper is equal check")
479                 .that(createdWrapper.equals(wrapper)).isTrue();
480     }
481 
482     @Test
getAudioAttributeWrapperFromUsage_withNonCriticalUsage_hashCode_succeeds()483     public void getAudioAttributeWrapperFromUsage_withNonCriticalUsage_hashCode_succeeds() {
484         CarAudioContext.AudioAttributesWrapper createdWrapper =
485                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_MEDIA);
486 
487         expectWithMessage("Non critical audio attributes wrapper hash code")
488                 .that(createdWrapper.hashCode()).isEqualTo(Integer.hashCode(USAGE_MEDIA));
489     }
490 
491     @Test
getAudioAttributeWrapperFromUsage_withCriticalUsage_succeeds()492     public void getAudioAttributeWrapperFromUsage_withCriticalUsage_succeeds() {
493         CarAudioContext.AudioAttributesWrapper wrapper =
494                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_EMERGENCY);
495 
496         expectWithMessage("Critical audio attributes for wrapper")
497                 .that(wrapper.getAudioAttributes()).isEqualTo(TEST_EMERGENCY_ATTRIBUTE);
498     }
499 
500     @Test
getAudioAttributeWrapperFromUsage_withCriticalUsage_toString_succeeds()501     public void getAudioAttributeWrapperFromUsage_withCriticalUsage_toString_succeeds() {
502         CarAudioContext.AudioAttributesWrapper wrapper =
503                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_EMERGENCY);
504 
505         expectWithMessage("Critical audio attributes for wrapper string")
506                 .that(wrapper.toString()).isEqualTo(TEST_EMERGENCY_ATTRIBUTE.toString());
507     }
508 
509     @Test
getAudioAttributeWrapperFromUsage_withCriticalUsage_equals_succeeds()510     public void getAudioAttributeWrapperFromUsage_withCriticalUsage_equals_succeeds() {
511         CarAudioContext.AudioAttributesWrapper wrapper =
512                 new CarAudioContext.AudioAttributesWrapper(TEST_EMERGENCY_ATTRIBUTE);
513 
514         CarAudioContext.AudioAttributesWrapper createdWrapper =
515                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_EMERGENCY);
516 
517         expectWithMessage("Critical audio attributes wrapper is equal check")
518                 .that(createdWrapper.equals(wrapper)).isTrue();
519     }
520 
521     @Test
getAudioAttributeWrapperFromUsage_withCriticalUsage_hashCode_succeeds()522     public void getAudioAttributeWrapperFromUsage_withCriticalUsage_hashCode_succeeds() {
523         CarAudioContext.AudioAttributesWrapper createdWrapper =
524                 CarAudioContext.getAudioAttributeWrapperFromUsage(USAGE_EMERGENCY);
525 
526         expectWithMessage("Critical audio attributes wrapper hash code")
527                 .that(createdWrapper.hashCode()).isEqualTo(Integer.hashCode(USAGE_EMERGENCY));
528     }
529 
530     @Test
getAudioAttributeFromUsage_withNonCriticalUsage_succeeds()531     public void getAudioAttributeFromUsage_withNonCriticalUsage_succeeds() {
532         AudioAttributes attributes = new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build();
533 
534         AudioAttributes createdAttributes = CarAudioContext.getAudioAttributeFromUsage(USAGE_MEDIA);
535 
536         expectWithMessage("Non critical audio attributes")
537                 .that(createdAttributes).isEqualTo(attributes);
538     }
539 
540     @Test
getAudioAttributeFromUsage_withCriticalUsage_succeeds()541     public void getAudioAttributeFromUsage_withCriticalUsage_succeeds() {
542         AudioAttributes attributes =
543                 new AudioAttributes.Builder().setSystemUsage(USAGE_EMERGENCY).build();
544 
545         AudioAttributes createdAttributes =
546                 CarAudioContext.getAudioAttributeFromUsage(USAGE_EMERGENCY);
547 
548         expectWithMessage("Critical audio attributes")
549                 .that(createdAttributes).isEqualTo(attributes);
550     }
551 
552     @Test
isRingerOrCallContext_withCallContext_returnsTrue()553     public void isRingerOrCallContext_withCallContext_returnsTrue() {
554         boolean isRingerOrCall = isRingerOrCallAudioAttribute(TEST_CALL_ATTRIBUTE);
555 
556         expectWithMessage("Is call check")
557                 .that(isRingerOrCall).isTrue();
558     }
559 
560     @Test
isRingerOrCallContext_withRingerContext_returnsTrue()561     public void isRingerOrCallContext_withRingerContext_returnsTrue() {
562         boolean isRingerOrCall = isRingerOrCallAudioAttribute(TEST_RINGER_ATTRIBUTE);
563 
564         expectWithMessage("Is ringer check")
565                 .that(isRingerOrCall).isTrue();
566     }
567 
568     @Test
isRingerOrCallContext_withNonCriticalContext_returnsFalse()569     public void isRingerOrCallContext_withNonCriticalContext_returnsFalse() {
570         boolean isRingerOrCall = isRingerOrCallAudioAttribute(TEST_MEDIA_ATTRIBUTE);
571 
572         expectWithMessage("Non critical context is ringer or call check")
573                 .that(isRingerOrCall).isFalse();
574     }
575 
576     @Test
isRingerOrCallContext_withCriticalContext_returnsFalse()577     public void isRingerOrCallContext_withCriticalContext_returnsFalse() {
578         boolean isRingerOrCall = isRingerOrCallAudioAttribute(TEST_EMERGENCY_ATTRIBUTE);
579 
580         expectWithMessage("Critical context is ringer or call check")
581                 .that(isRingerOrCall).isFalse();
582     }
583 
584     @Test
preconditionCheckAudioContext_withNonExistentContext_throws()585     public void preconditionCheckAudioContext_withNonExistentContext_throws() {
586         IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
587             TEST_CAR_AUDIO_CONTEXT.preconditionCheckAudioContext(-TEST_EMERGENCY_CONTEXT);
588         });
589 
590         expectWithMessage("Precondition exception with non existent context check")
591                 .that(thrown).hasMessageThat()
592                 .contains("Car audio context " + -TEST_EMERGENCY_CONTEXT + " is invalid");
593     }
594 
595     @Test
preconditionCheckAudioContext_withInvalidContext_throws()596     public void preconditionCheckAudioContext_withInvalidContext_throws() {
597         IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> {
598             TEST_CAR_AUDIO_CONTEXT.preconditionCheckAudioContext(INVALID_CONTEXT);
599         });
600 
601         expectWithMessage("Precondition exception with invalid context check")
602                 .that(thrown).hasMessageThat()
603                 .contains("Car audio context " + INVALID_CONTEXT + " is invalid");
604     }
605 
606     @Test
getSystemUsages_returnsAllSystemUsages()607     public void getSystemUsages_returnsAllSystemUsages() {
608         int[] systemUsages = CarAudioContext.getSystemUsages();
609 
610         expectWithMessage("System Usages")
611                 .that(systemUsages).asList().containsExactly(
612                         USAGE_CALL_ASSISTANT,
613                         USAGE_EMERGENCY,
614                         USAGE_SAFETY,
615                         USAGE_VEHICLE_STATUS,
616                         USAGE_ANNOUNCEMENT);
617     }
618 
619     @Test
toString_forNonSystemSoundsContexts_returnsStrings()620     public void toString_forNonSystemSoundsContexts_returnsStrings() {
621         expectWithMessage("Context String for INVALID")
622                 .that(TEST_CAR_AUDIO_CONTEXT.toString(CarAudioContext.getInvalidContext()))
623                 .isEqualTo("INVALID");
624         expectWithMessage("Context String for MUSIC")
625                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_MEDIA_CONTEXT)).isEqualTo("MUSIC");
626         expectWithMessage("Context String for NAVIGATION")
627                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_NAVIGATION_CONTEXT))
628                 .isEqualTo("NAVIGATION");
629         expectWithMessage("Context String for VOICE_COMMAND")
630                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_ASSISTANT_CONTEXT))
631                 .isEqualTo("VOICE_COMMAND");
632         expectWithMessage("Context String for CALL_RING")
633                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_CALL_RING_CONTEXT))
634                 .isEqualTo("CALL_RING");
635         expectWithMessage("Context String for CALL")
636                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_CALL_CONTEXT)).isEqualTo("CALL");
637         expectWithMessage("Context String for ALARM")
638                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_ALARM_CONTEXT)).isEqualTo("ALARM");
639         expectWithMessage("Context String for NOTIFICATION")
640                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_NOTIFICATION_CONTEXT))
641                 .isEqualTo("NOTIFICATION");
642     }
643 
644     @Test
toString_forSystemSoundsContexts_returnsStrings()645     public void toString_forSystemSoundsContexts_returnsStrings() {
646         expectWithMessage("Context String for SYSTEM_SOUND")
647                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_SYSTEM_SOUND_CONTEXT))
648                 .isEqualTo("SYSTEM_SOUND");
649         expectWithMessage("Context String for EMERGENCY")
650                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_EMERGENCY_CONTEXT))
651                 .isEqualTo("EMERGENCY");
652         expectWithMessage("Context String for SAFETY")
653                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_SAFETY_CONTEXT)).isEqualTo("SAFETY");
654         expectWithMessage("Context String for VEHICLE_STATUS")
655                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_VEHICLE_STATUS_CONTEXT))
656                 .isEqualTo("VEHICLE_STATUS");
657         expectWithMessage("Context String for ANNOUNCEMENT")
658                 .that(TEST_CAR_AUDIO_CONTEXT.toString(TEST_ANNOUNCEMENT_CONTEXT))
659                 .isEqualTo("ANNOUNCEMENT");
660     }
661 
662     @Test
toString_forInvalidContext_returnsUnsupportedContext()663     public void toString_forInvalidContext_returnsUnsupportedContext() {
664         expectWithMessage("Context String for invalid context")
665                 .that(TEST_CAR_AUDIO_CONTEXT.toString(/* audioContext= */ -1))
666                 .contains("Unsupported Context");
667     }
668 
669     @Test
getAllContextIds_returnsAllContext()670     public void getAllContextIds_returnsAllContext() {
671         expectWithMessage("All context IDs")
672                 .that(TEST_CAR_AUDIO_CONTEXT.getAllContextsIds())
673                 .containsExactly(TEST_MEDIA_CONTEXT,
674                         TEST_NAVIGATION_CONTEXT,
675                         TEST_ASSISTANT_CONTEXT,
676                         TEST_CALL_RING_CONTEXT,
677                         TEST_CALL_CONTEXT,
678                         TEST_ALARM_CONTEXT,
679                         TEST_NOTIFICATION_CONTEXT,
680                         TEST_SYSTEM_SOUND_CONTEXT,
681                         TEST_EMERGENCY_CONTEXT,
682                         TEST_SAFETY_CONTEXT,
683                         TEST_VEHICLE_STATUS_CONTEXT,
684                         TEST_ANNOUNCEMENT_CONTEXT);
685     }
686 
687     @Test
getAllContextIds_failsForInvalid()688     public void getAllContextIds_failsForInvalid() {
689         expectWithMessage("All context IDs")
690                 .that(TEST_CAR_AUDIO_CONTEXT.getAllContextsIds())
691                 .doesNotContain(CarAudioContext.getInvalidContext());
692     }
693 
694     @Test
getCarSystemContextIds()695     public void getCarSystemContextIds() {
696         List<Integer> systemContextIds = CarAudioContext.getCarSystemContextIds();
697 
698         expectWithMessage("Car audio system contexts")
699                 .that(systemContextIds)
700                 .containsExactly(TEST_EMERGENCY_CONTEXT, TEST_SAFETY_CONTEXT,
701                         TEST_VEHICLE_STATUS_CONTEXT, TEST_ANNOUNCEMENT_CONTEXT);
702     }
703 
704     @Test
getNonCarSystemContextIds()705     public void getNonCarSystemContextIds() {
706         List<Integer> nonCarSystemContextIds = CarAudioContext.getNonCarSystemContextIds();
707 
708         expectWithMessage("Car audio non system contexts")
709                 .that(nonCarSystemContextIds)
710                 .containsExactly(TEST_MEDIA_CONTEXT, TEST_NAVIGATION_CONTEXT,
711                         TEST_ASSISTANT_CONTEXT, TEST_CALL_RING_CONTEXT,
712                         TEST_CALL_CONTEXT,
713                         TEST_ALARM_CONTEXT, TEST_NOTIFICATION_CONTEXT,
714                         TEST_SYSTEM_SOUND_CONTEXT);
715     }
716 
717     @Test
validateAllAudioAttributesSupported()718     public void validateAllAudioAttributesSupported() {
719         boolean valid = TEST_CAR_AUDIO_CONTEXT.validateAllAudioAttributesSupported(
720                 TEST_CAR_AUDIO_CONTEXT.getAllContextsIds());
721 
722         expectWithMessage("All audio attributes are supported flag")
723                 .that(valid).isTrue();
724     }
725 
726     @Test
validateAllAudioAttributesSupported_forNonCarSystemContextsOnly_fails()727     public void validateAllAudioAttributesSupported_forNonCarSystemContextsOnly_fails() {
728         boolean valid = TEST_CAR_AUDIO_CONTEXT.validateAllAudioAttributesSupported(
729                 CarAudioContext.getNonCarSystemContextIds());
730 
731         expectWithMessage("Missing car audio system audio attributes are supported flag")
732                 .that(valid).isFalse();
733     }
734 
735     @Test
validateAllAudioAttributesSupported_forCarSystemContextsOnly_fails()736     public void validateAllAudioAttributesSupported_forCarSystemContextsOnly_fails() {
737         boolean valid = TEST_CAR_AUDIO_CONTEXT.validateAllAudioAttributesSupported(
738                 CarAudioContext.getCarSystemContextIds());
739 
740         expectWithMessage("Missing non car audio system audio attributes are supported flag")
741                 .that(valid).isFalse();
742     }
743 
744     @Test
getAllContextsInfo()745     public void getAllContextsInfo() {
746         Set<Integer> allContextIds =
747                 new ArraySet<Integer>(TEST_CAR_AUDIO_CONTEXT.getAllContextsIds());
748         allContextIds.add(CarAudioContext.getInvalidContext());
749 
750         List<CarAudioContextInfo> contextInfos = CarAudioContext.getAllContextsInfo();
751 
752         for (CarAudioContextInfo info : contextInfos) {
753             expectWithMessage("Context info id for %s", info)
754                     .that(info.getId()).isIn(allContextIds);
755         }
756     }
757 
758     @Test
getAllContextsInfo_sameSizeAsGetAllContextsIds()759     public void getAllContextsInfo_sameSizeAsGetAllContextsIds() {
760         Set<Integer> allContextIds =
761                 new ArraySet<Integer>(TEST_CAR_AUDIO_CONTEXT.getAllContextsIds());
762         allContextIds.add(CarAudioContext.getInvalidContext());
763 
764         List<CarAudioContextInfo> contextInfos = CarAudioContext.getAllContextsInfo();
765 
766         expectWithMessage("All contexts info size")
767                 .that(contextInfos.size()).isEqualTo(allContextIds.size());
768     }
769 
770     @Test
getInvalidContext()771     public void getInvalidContext() {
772         expectWithMessage("Invalid context id")
773                 .that(CarAudioContext.getInvalidContext()).isEqualTo(INVALID_CONTEXT_ID);
774     }
775 
776     @Test
isInvalidContext()777     public void isInvalidContext() {
778         expectWithMessage("Is invalid context id")
779                 .that(CarAudioContext.isInvalidContextId(INVALID_CONTEXT_ID)).isTrue();
780     }
781 
782     @Test
audioAttributeMatches_onWrapper_withMatchingAudioAttributes()783     public void audioAttributeMatches_onWrapper_withMatchingAudioAttributes() {
784         AudioAttributes mediaAudioAttribute =
785                 new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build();
786         AudioAttributes mediaAudioAttributeMatched =
787                 new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build();
788 
789         expectWithMessage("Wrapper audio attribute's %s and %s matched results",
790                 mediaAudioAttribute, mediaAudioAttributeMatched)
791                 .that(CarAudioContext.AudioAttributesWrapper
792                         .audioAttributeMatches(mediaAudioAttribute, mediaAudioAttributeMatched))
793                 .isTrue();
794     }
795 
796     @Test
audioAttributeMatches_onWrapper_withNonMatchingAudioAttributes()797     public void audioAttributeMatches_onWrapper_withNonMatchingAudioAttributes() {
798         AudioAttributes mediaAudioAttribute =
799                 new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build();
800         AudioAttributes gameAudioAttributeMatched =
801                 new AudioAttributes.Builder().setUsage(USAGE_GAME).build();
802 
803         expectWithMessage("Wrapper audio attribute's %s and %s non-matched results",
804                 mediaAudioAttribute, gameAudioAttributeMatched)
805                 .that(CarAudioContext.AudioAttributesWrapper
806                         .audioAttributeMatches(mediaAudioAttribute, gameAudioAttributeMatched))
807                 .isFalse();
808     }
809 
810     @Test
constructor_withNullContextInfos_fails()811     public void constructor_withNullContextInfos_fails() {
812         NullPointerException thrown = assertThrows(NullPointerException.class,
813                 () -> new CarAudioContext(/* carAudioContexts= */ null,
814                         /* useCoreAudioRouting= */ false));
815 
816         expectWithMessage("Constructor exception")
817                 .that(thrown).hasMessageThat()
818                 .contains("Car audio contexts");
819     }
820 
821     @Test
constructor_withEmptyContextInfos_fails()822     public void constructor_withEmptyContextInfos_fails() {
823         IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
824                 () -> new CarAudioContext(/* carAudioContexts= */ Collections.EMPTY_LIST,
825                         /* useCoreAudioRouting= */ false));
826 
827         expectWithMessage("Empty list constructor exception")
828                 .that(thrown).hasMessageThat()
829                 .contains("Car audio contexts must not be empty");
830     }
831 
832     @Test
getAllCarSystemContextInfo_verifyContents()833     public void getAllCarSystemContextInfo_verifyContents() {
834         Set<Integer> carContextIds =
835                 new ArraySet<Integer>(TEST_CAR_AUDIO_CONTEXT.getCarSystemContextIds());
836 
837         List<CarAudioContextInfo> carContextInfo = CarAudioContext.getAllCarSystemContextsInfo();
838 
839         expectWithMessage("Car system context info size").that(carContextInfo)
840                 .hasSize(carContextIds.size());
841         for (CarAudioContextInfo info : carContextInfo) {
842             expectWithMessage("Context info id for %s", info)
843                     .that(info.getId()).isIn(carContextIds);
844         }
845     }
846 
847     @Test
getAllNonCarSystemContextInfo_verifyContents()848     public void getAllNonCarSystemContextInfo_verifyContents() {
849         Set<Integer> nonCarContextIds =
850                 new ArraySet<Integer>(TEST_CAR_AUDIO_CONTEXT.getNonCarSystemContextIds());
851 
852         List<CarAudioContextInfo> nonCarContextInfo =
853                 CarAudioContext.getAllNonCarSystemContextsInfo();
854 
855         expectWithMessage("Non car system context info size").that(nonCarContextInfo)
856                 .hasSize(nonCarContextIds.size());
857         for (CarAudioContextInfo info : nonCarContextInfo) {
858             expectWithMessage("Context info id for %s", info)
859                     .that(info.getId()).isIn(nonCarContextIds);
860         }
861     }
862 
863     @Test
evaluateAttributesToDuck()864     public void evaluateAttributesToDuck() {
865         List<AudioAttributes> focusHolders = Collections.EMPTY_LIST;
866 
867         List<AudioAttributes> attributesToDuck =
868                 CarAudioContext.evaluateAudioAttributesToDuck(focusHolders);
869 
870         expectWithMessage("Audio attributes to duck").that(attributesToDuck).isEmpty();
871     }
872 
873     @Test
evaluateAudioAttributesToDuck_withMedia()874     public void evaluateAudioAttributesToDuck_withMedia() {
875         List<AudioAttributes> focusHolders = List.of(TEST_MEDIA_ATTRIBUTE);
876 
877         List<AudioAttributes> attributesToDuck =
878                 CarAudioContext.evaluateAudioAttributesToDuck(focusHolders);
879 
880         expectWithMessage("Audio attributes to duck with media")
881                 .that(attributesToDuck).isEmpty();
882     }
883 
884     @Test
evaluateAudioAttributesToDuck_withCallAndEmergency()885     public void evaluateAudioAttributesToDuck_withCallAndEmergency() {
886         List<AudioAttributes> focusHolders =
887                 List.of(TEST_EMERGENCY_ATTRIBUTE, TEST_CALL_ATTRIBUTE);
888 
889         List<AudioAttributes> attributesToDuck =
890                 CarAudioContext.evaluateAudioAttributesToDuck(focusHolders);
891 
892         expectWithMessage("Audio attributes to duck with media and emergency")
893                 .that(attributesToDuck).containsExactly(TEST_CALL_ATTRIBUTE);
894     }
895 
896     @Test
isOemExtensionAudioContext_returnsAlwaysFalse()897     public void isOemExtensionAudioContext_returnsAlwaysFalse() {
898         for (@AudioContext int audioContext : TEST_CAR_AUDIO_CONTEXT.getAllContextsIds()) {
899             expectWithMessage("When using core audio routing, not oem extnesion expected")
900                     .that(TEST_CAR_AUDIO_CONTEXT.isOemExtensionAudioContext(audioContext))
901                     .isEqualTo(false);
902         }
903     }
904 
905     @Test
getAudioAttributeWrapperFromAttributes_withMusic_hashCode_succeeds()906     public void getAudioAttributeWrapperFromAttributes_withMusic_hashCode_succeeds() {
907         CarAudioContext carAudioContextUsingCoreRouting = new CarAudioContext(
908                 CoreAudioRoutingUtils.getCarAudioContextInfos(), /* useCoreAudioRouting= */ true);
909 
910         CarAudioContext.AudioAttributesWrapper createdWrapper =
911                 carAudioContextUsingCoreRouting.getAudioAttributeWrapperFromAttributes(
912                         CoreAudioRoutingUtils.MUSIC_ATTRIBUTES);
913 
914         expectWithMessage("Music strategy audio attributes wrapper hash code")
915                 .that(createdWrapper.hashCode()).isEqualTo(Integer.hashCode(
916                         CoreAudioRoutingUtils.MUSIC_STRATEGY_ID));
917     }
918 
919     @Test
getAudioAttributeWrapperFromAttributes_withOemExtension_hashCode_succeeds()920     public void getAudioAttributeWrapperFromAttributes_withOemExtension_hashCode_succeeds() {
921         CarAudioContext carAudioContextUsingCoreRouting = new CarAudioContext(
922                 CoreAudioRoutingUtils.getCarAudioContextInfos(), /* useCoreAudioRouting= */ true);
923 
924         CarAudioContext.AudioAttributesWrapper createdWrapper =
925                 carAudioContextUsingCoreRouting.getAudioAttributeWrapperFromAttributes(
926                         CoreAudioRoutingUtils.OEM_ATTRIBUTES);
927 
928         expectWithMessage("OEM strategy audio attributes wrapper hash code")
929                 .that(createdWrapper.hashCode()).isEqualTo(Integer.hashCode(
930                         CoreAudioRoutingUtils.OEM_STRATEGY_ID));
931     }
932 
933     @Test
getLegacyContextForUsage()934     public void getLegacyContextForUsage() {
935         List<Integer> usages = List.of(USAGE_ALARM, USAGE_ANNOUNCEMENT, USAGE_VIRTUAL_SOURCE,
936                 USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, USAGE_ASSISTANCE_SONIFICATION,
937                 USAGE_ASSISTANT, USAGE_CALL_ASSISTANT, USAGE_EMERGENCY, USAGE_GAME, USAGE_MEDIA,
938                 USAGE_NOTIFICATION, USAGE_NOTIFICATION_EVENT, USAGE_NOTIFICATION_RINGTONE,
939                 USAGE_SAFETY, USAGE_UNKNOWN, USAGE_VEHICLE_STATUS,  USAGE_VOICE_COMMUNICATION);
940 
941         for (int usage: usages) {
942             AudioAttributes attributes = CarAudioContext.getAudioAttributeFromUsage(usage);
943 
944             expectWithMessage("Legacy car audio context for usage %s",
945                     DebugUtils.constantToString(AudioAttributes.class, "USAGE_", usage))
946                     .that(CarAudioContext.getLegacyContextForUsage(usage))
947                     .isEqualTo(TEST_CAR_AUDIO_CONTEXT.getContextForAudioAttribute(attributes));
948         }
949     }
950 
951     @Test
getContextsInfo()952     public void getContextsInfo() {
953         List<CarAudioContextInfo> audioContextInfos = CoreAudioRoutingUtils
954                 .getCarAudioContextInfos();
955         CarAudioContext carAudioContext = new CarAudioContext(audioContextInfos,
956                 /* useCoreAudioRouting= */ true);
957 
958         expectWithMessage("Context infos").that(carAudioContext.getContextsInfo())
959                 .containsExactlyElementsIn(audioContextInfos);
960     }
961 
962     @Test
getCarAudioContextId_forAudioAttributesWrapper()963     public void getCarAudioContextId_forAudioAttributesWrapper() {
964         int contextId = 1;
965         CarAudioContext.AudioAttributesWrapper wrapper =
966                 new CarAudioContext.AudioAttributesWrapper(TEST_MEDIA_ATTRIBUTE, contextId);
967 
968         expectWithMessage("Car audio context Id").that(wrapper.getCarAudioContextId())
969                 .isEqualTo(contextId);
970     }
971 }
972