• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.car.audio;
18 
19 import static android.hardware.automotive.audiocontrol.VolumeInvocationType.ON_BOOT;
20 import static android.media.audio.common.AudioUsage.ALARM;
21 import static android.media.audio.common.AudioUsage.ANNOUNCEMENT;
22 import static android.media.audio.common.AudioUsage.ASSISTANCE_ACCESSIBILITY;
23 import static android.media.audio.common.AudioUsage.ASSISTANCE_SONIFICATION;
24 import static android.media.audio.common.AudioUsage.ASSISTANT;
25 import static android.media.audio.common.AudioUsage.CALL_ASSISTANT;
26 import static android.media.audio.common.AudioUsage.EMERGENCY;
27 import static android.media.audio.common.AudioUsage.GAME;
28 import static android.media.audio.common.AudioUsage.MEDIA;
29 import static android.media.audio.common.AudioUsage.NOTIFICATION;
30 import static android.media.audio.common.AudioUsage.NOTIFICATION_EVENT;
31 import static android.media.audio.common.AudioUsage.NOTIFICATION_TELEPHONY_RINGTONE;
32 import static android.media.audio.common.AudioUsage.SAFETY;
33 import static android.media.audio.common.AudioUsage.UNKNOWN;
34 import static android.media.audio.common.AudioUsage.VEHICLE_STATUS;
35 import static android.media.audio.common.AudioUsage.VOICE_COMMUNICATION;
36 import static android.media.audio.common.AudioUsage.VOICE_COMMUNICATION_SIGNALLING;
37 
38 import static com.android.car.audio.CarAudioContext.getAudioAttributeFromUsage;
39 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.MEDIA_TEST_DEVICE;
40 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.NAVIGATION_TEST_DEVICE;
41 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.OEM_TEST_DEVICE;
42 import static com.android.car.audio.CarAudioTestUtils.TEST_ACTIVATION;
43 import static com.android.car.audio.CarAudioTestUtils.TEST_ALARM_ATTRIBUTE;
44 import static com.android.car.audio.CarAudioTestUtils.TEST_ANNOUNCEMENT_ATTRIBUTE;
45 import static com.android.car.audio.CarAudioTestUtils.TEST_ASSISTANT_ATTRIBUTE;
46 import static com.android.car.audio.CarAudioTestUtils.TEST_CALL_ATTRIBUTE;
47 import static com.android.car.audio.CarAudioTestUtils.TEST_EMERGENCY_ATTRIBUTE;
48 import static com.android.car.audio.CarAudioTestUtils.TEST_GAME_USAGE_ATTRIBUTE;
49 import static com.android.car.audio.CarAudioTestUtils.TEST_MAX_ACTIVATION;
50 import static com.android.car.audio.CarAudioTestUtils.TEST_MEDIA_ATTRIBUTE;
51 import static com.android.car.audio.CarAudioTestUtils.TEST_MIN_ACTIVATION;
52 import static com.android.car.audio.CarAudioTestUtils.TEST_NOTIFICATION_ATTRIBUTE;
53 import static com.android.car.audio.CarAudioTestUtils.TEST_NOTIFICATION_EVENT_ATTRIBUTE;
54 import static com.android.car.audio.CarAudioTestUtils.TEST_RINGER_ATTRIBUTE;
55 import static com.android.car.audio.CarAudioTestUtils.TEST_SAFETY_ATTRIBUTE;
56 import static com.android.car.audio.CarAudioTestUtils.TEST_SYSTEM_ATTRIBUTE;
57 import static com.android.car.audio.CarAudioTestUtils.TEST_UNKNOWN_USAGE_ATTRIBUTE;
58 import static com.android.car.audio.CarAudioTestUtils.TEST_VEHICLE_ATTRIBUTE;
59 import static com.android.car.audio.CarAudioTestUtils.createBusAudioPort;
60 import static com.android.car.audio.CarAudioTestUtils.createDeviceToContextEntry;
61 import static com.android.car.audio.CarAudioTestUtils.createListOfHALAudioAttributes;
62 import static com.android.car.audio.CarAudioTestUtils.createVolumeActivationConfiguration;
63 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
64 
65 import static com.google.common.collect.Sets.newHashSet;
66 
67 import android.hardware.automotive.audiocontrol.AudioZone;
68 import android.hardware.automotive.audiocontrol.AudioZoneConfig;
69 import android.hardware.automotive.audiocontrol.AudioZoneContext;
70 import android.hardware.automotive.audiocontrol.AudioZoneContextInfo;
71 import android.hardware.automotive.audiocontrol.DeviceToContextEntry;
72 import android.hardware.automotive.audiocontrol.VolumeGroupConfig;
73 import android.media.AudioAttributes;
74 import android.media.MediaRecorder;
75 import android.media.audio.common.AudioContentType;
76 import android.media.audio.common.AudioHalProductStrategy;
77 import android.media.audio.common.AudioUsage;
78 import android.media.audiopolicy.AudioProductStrategy;
79 import android.media.audiopolicy.AudioVolumeGroup;
80 import android.os.Parcel;
81 
82 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
83 
84 import java.util.ArrayList;
85 import java.util.List;
86 
87 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
88 public final class CoreAudioRoutingUtils {
89 
90     public static final int MUSIC_MIN_INDEX = 0;
91     public static final int MUSIC_MAX_INDEX = 40;
92     public static final int MUSIC_AM_INIT_INDEX = 8;
93     public static final int NAV_MIN_INDEX = 5;
94     public static final int NAV_MAX_INDEX = 35;
95     public static final int OEM_MIN_INDEX = 1;
96     public static final int OEM_MAX_INDEX = 15;
97     public static final int MUSIC_CAR_GROUP_ID = 0;
98     public static final int OEM_CAR_GROUP_ID = 2;
99     public static final int NAV_CAR_GROUP_ID = 1;
100     public static final String MUSIC_DEVICE_ADDRESS = "MUSIC_DEVICE_ADDRESS";
101     public static final String NAV_DEVICE_ADDRESS = "NAV_DEVICE_ADDRESS";
102     public static final String OEM_DEVICE_ADDRESS = "OEM_DEVICE_ADDRESS";
103     public static final List<AudioVolumeGroup> VOLUME_GROUPS;
104     public static final List<AudioProductStrategy> PRODUCT_STRATEGIES;
105 
106     public static final AudioAttributes MUSIC_ATTRIBUTES = new AudioAttributes.Builder()
107             .setUsage(AudioAttributes.USAGE_MEDIA)
108             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
109             .build();
110 
111     public static final AudioAttributes MOVIE_ATTRIBUTES = new AudioAttributes.Builder()
112             .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE)
113             .build();
114     public static final int MUSIC_STRATEGY_ID = 777;
115     public static final String MUSIC_CONTEXT_NAME = "MUSIC_CONTEXT";
116     public static final int MUSIC_GROUP_ID = 666;
117     public static final String MUSIC_GROUP_NAME = "MUSIC_GROUP";
118     public static final AudioProductStrategy MUSIC_STRATEGY;
119     public static final AudioVolumeGroup MUSIC_GROUP;
120     public static final CarAudioContextInfo MEDIA_CONTEXT_INFO;
121 
122     public static final AudioAttributes NAV_ATTRIBUTES = new AudioAttributes.Builder()
123             .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
124             .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
125             .build();
126     public static final int NAV_STRATEGY_ID = 99;
127     public static final String NAV_CONTEXT_NAME = "NAV_CONTEXT";
128     public static final int NAV_GROUP_ID = 8;
129     public static final String NAV_GROUP_NAME = "NAV_GROUP";
130     public static final AudioProductStrategy NAV_STRATEGY;
131     public static final AudioVolumeGroup NAV_GROUP;
132     public static final CarAudioContextInfo NAV_CONTEXT_INFO;
133 
134     public static final AudioAttributes OEM_ATTRIBUTES;
135     public static final int OEM_STRATEGY_ID = 1979;
136     public static final String OEM_CONTEXT_NAME = "OEM_CONTEXT";
137     public static final int OEM_GROUP_ID = 55;
138     public static final String OEM_GROUP_NAME = "OEM_GROUP";
139     public static final String OEM_FORMATTED_TAGS = "oem=extension_1979";
140     public static final AudioProductStrategy OEM_STRATEGY;
141     public static final AudioVolumeGroup OEM_GROUP;
142     public static final CarAudioContextInfo OEM_CONTEXT_INFO;
143 
144     static final String INVALID_CONTEXT_NAME = "INVALID_CONTEXT";
145     static final int INVALID_STRATEGY_ID = 999999;
146     static final int INVALID_GROUP_ID = 999999;
147     static final String INVALID_GROUP_NAME = "INVALID_GROUP";
148 
149     static final int INVALID_STRATEGY = -1;
150     public static final String CORE_PRIMARY_ZONE = "Core primary zone";
151 
152     static final AudioAttributes UNSUPPORTED_ATTRIBUTES = new AudioAttributes.Builder()
153             .setUsage(AudioAttributes.USAGE_GAME)
154             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
155             .build();
156     public static final int TEST_MEDIA_PORT_ID = 1979;
157     public static final int TEST_NAVIGATION_PORT_ID = 867;
158     public static final int TEST_OEM_PORT_ID = 5309;
159 
160     static {
161         OEM_ATTRIBUTES = new AudioAttributes.Builder()
162                 .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
163                 .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
164                 .replaceTags(newHashSet(OEM_FORMATTED_TAGS))
165                 .build();
166         // Note: constructors are private, use marshalling public API to generate the mocks
167         Parcel parcel = Parcel.obtain();
168         // marshall AudioProductStrategy data
169         parcel.writeString(MUSIC_CONTEXT_NAME);
170         parcel.writeInt(MUSIC_STRATEGY_ID);
171 
172         // nb attributes groups
173         parcel.writeInt(1);
174         parcel.writeInt(MUSIC_GROUP_ID);
175         // stream type
176         parcel.writeInt(0);
177         // nb attributes
178         parcel.writeInt(2);
179 
180         parcel.writeInt(AudioAttributes.USAGE_MEDIA);
181         parcel.writeInt(AudioAttributes.CONTENT_TYPE_MUSIC);
182         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
183         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
184         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
185         // mFormattedTags
186         parcel.writeString("");
187         // ATTR_PARCEL_IS_NULL_BUNDLE
188         parcel.writeInt(-1977);
189 
190         parcel.writeInt(AudioAttributes.USAGE_UNKNOWN);
191         parcel.writeInt(AudioAttributes.CONTENT_TYPE_UNKNOWN);
192         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
193         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
194         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
195         // mFormattedTags
196         parcel.writeString("");
197         // ATTR_PARCEL_IS_NULL_BUNDLE
198         parcel.writeInt(-1977);
199 
200         parcel.setDataPosition(0);
201         MUSIC_STRATEGY = AudioProductStrategy.CREATOR.createFromParcel(parcel);
parcel.recycle()202         parcel.recycle();
203 
204         parcel = Parcel.obtain();
205         // marshall AudioProductStrategy data
206         parcel.writeString(NAV_CONTEXT_NAME);
207         parcel.writeInt(NAV_STRATEGY_ID);
208 
209         // nb attributes groups
210         parcel.writeInt(1);
211         parcel.writeInt(NAV_GROUP_ID);
212         // stream type
213         parcel.writeInt(0);
214         // nb attributes
215         parcel.writeInt(2);
216 
217         parcel.writeInt(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
218         parcel.writeInt(AudioAttributes.CONTENT_TYPE_SPEECH);
219         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
220         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
221         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
222         // mFormattedTags
223         parcel.writeString("");
224         // ATTR_PARCEL_IS_NULL_BUNDLE
225         parcel.writeInt(-1977);
226 
227         parcel.writeInt(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
228         parcel.writeInt(AudioAttributes.CONTENT_TYPE_UNKNOWN);
229         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
230         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
231         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
232         // mFormattedTags
233         parcel.writeString("");
234         // ATTR_PARCEL_IS_NULL_BUNDLE
235         parcel.writeInt(-1977);
236 
237         parcel.setDataPosition(0);
238         NAV_STRATEGY = AudioProductStrategy.CREATOR.createFromParcel(parcel);
parcel.recycle()239         parcel.recycle();
240 
241         parcel = Parcel.obtain();
242         // marshall AudioProductStrategy data
243         parcel.writeString(OEM_CONTEXT_NAME);
244         parcel.writeInt(OEM_STRATEGY_ID);
245 
246         // nb attributes groups
247         parcel.writeInt(1);
248         parcel.writeInt(OEM_GROUP_ID);
249         // stream type
250         parcel.writeInt(0);
251         // nb attributes
252         parcel.writeInt(1);
253         parcel.writeInt(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
254         parcel.writeInt(AudioAttributes.CONTENT_TYPE_SPEECH);
255         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
256         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
257         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
258         parcel.writeString(OEM_FORMATTED_TAGS);
259         // ATTR_PARCEL_IS_NULL_BUNDLE
260         parcel.writeInt(-1977);
261 
262         parcel.setDataPosition(0);
263         OEM_STRATEGY = AudioProductStrategy.CREATOR.createFromParcel(parcel);
parcel.recycle()264         parcel.recycle();
265 
266         // Order matters, put the default in the middle to check default strategy is not selected
267         // if not explicitly requested.
268         PRODUCT_STRATEGIES = List.of(OEM_STRATEGY, MUSIC_STRATEGY, NAV_STRATEGY);
269 
270         parcel = Parcel.obtain();
271         // marshall AudioVolumeGroup data
272         parcel.writeString(MUSIC_GROUP_NAME);
273         parcel.writeInt(MUSIC_GROUP_ID);
274 
275         // nb attributes
276         parcel.writeInt(2);
277         parcel.writeInt(AudioAttributes.USAGE_MEDIA);
278         parcel.writeInt(AudioAttributes.CONTENT_TYPE_MUSIC);
279         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
280         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
281         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
282         // mFormattedTags
283         parcel.writeString("");
284         // ATTR_PARCEL_IS_NULL_BUNDLE
285         parcel.writeInt(-1977);
286 
287         parcel.writeInt(AudioAttributes.USAGE_UNKNOWN);
288         parcel.writeInt(AudioAttributes.CONTENT_TYPE_UNKNOWN);
289         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
290         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
291         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
292         // mFormattedTags
293         parcel.writeString("");
294         // ATTR_PARCEL_IS_NULL_BUNDLE
295         parcel.writeInt(-1977);
296 
297         // nb stream types
298         parcel.writeInt(0);
299 
300         parcel.setDataPosition(0);
301         MUSIC_GROUP = AudioVolumeGroup.CREATOR.createFromParcel(parcel);
parcel.recycle()302         parcel.recycle();
303 
304         parcel = Parcel.obtain();
305         // marshall AudioProductStrategy data
306         parcel.writeString(NAV_GROUP_NAME);
307         parcel.writeInt(NAV_GROUP_ID);
308 
309         // nb attributes
310         parcel.writeInt(1);
311         parcel.writeInt(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
312         parcel.writeInt(AudioAttributes.CONTENT_TYPE_SPEECH);
313         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
314         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
315         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
316         // mFormattedTags
317         parcel.writeString("");
318         // ATTR_PARCEL_IS_NULL_BUNDLE
319         parcel.writeInt(-1977);
320 
321         parcel.writeInt(/* nb stream types= */ 0);
322 
323         parcel.setDataPosition(0);
324         NAV_GROUP = AudioVolumeGroup.CREATOR.createFromParcel(parcel);
parcel.recycle()325         parcel.recycle();
326 
327         parcel = Parcel.obtain();
328         // marshall AudioProductStrategy data
329         parcel.writeString(OEM_GROUP_NAME);
330         parcel.writeInt(OEM_GROUP_ID);
331 
332         // nb attributes
333         parcel.writeInt(1);
334         parcel.writeInt(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
335         parcel.writeInt(AudioAttributes.CONTENT_TYPE_SPEECH);
336         parcel.writeInt(MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID);
337         parcel.writeInt(AudioAttributes.FLAG_MUTE_HAPTIC);
338         parcel.writeInt(AudioAttributes.FLATTEN_TAGS);
339         // mFormattedTags
340         parcel.writeString("oem=extension_1979");
341         // ATTR_PARCEL_IS_NULL_BUNDLE
342         parcel.writeInt(-1977);
343 
344         // nb stream types
345         parcel.writeInt(0);
346 
347         parcel.setDataPosition(0);
348         OEM_GROUP = AudioVolumeGroup.CREATOR.createFromParcel(parcel);
parcel.recycle()349         parcel.recycle();
350 
351         VOLUME_GROUPS = List.of(MUSIC_GROUP, NAV_GROUP, OEM_GROUP);
352 
353         AudioAttributes[] oemAttributesArray = { OEM_ATTRIBUTES };
354         AudioAttributes[] musicAttributesArray = {MUSIC_ATTRIBUTES, MOVIE_ATTRIBUTES,
355                 TEST_NOTIFICATION_ATTRIBUTE, TEST_NOTIFICATION_EVENT_ATTRIBUTE,
356                 TEST_SYSTEM_ATTRIBUTE, TEST_ALARM_ATTRIBUTE, TEST_CALL_ATTRIBUTE,
357                 getAudioAttributeFromUsage(AudioAttributes.USAGE_CALL_ASSISTANT),
358                 getAudioAttributeFromUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING),
359                 TEST_RINGER_ATTRIBUTE, TEST_UNKNOWN_USAGE_ATTRIBUTE, TEST_GAME_USAGE_ATTRIBUTE,
360                 TEST_MEDIA_ATTRIBUTE,
361                 getAudioAttributeFromUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY),
362                 TEST_ASSISTANT_ATTRIBUTE, TEST_EMERGENCY_ATTRIBUTE, TEST_SAFETY_ATTRIBUTE,
363                 TEST_VEHICLE_ATTRIBUTE, TEST_ANNOUNCEMENT_ATTRIBUTE};
364         AudioAttributes[] navAttributesArray = { NAV_ATTRIBUTES };
365 
366         MEDIA_CONTEXT_INFO = new CarAudioContextInfo(musicAttributesArray, MUSIC_CONTEXT_NAME,
367                 MUSIC_STRATEGY_ID);
368         NAV_CONTEXT_INFO = new CarAudioContextInfo(navAttributesArray,  NAV_CONTEXT_NAME,
369                 NAV_STRATEGY_ID);
370         OEM_CONTEXT_INFO = new CarAudioContextInfo(oemAttributesArray, OEM_CONTEXT_NAME,
371                 OEM_STRATEGY_ID);
372     }
373 
CoreAudioRoutingUtils()374     private CoreAudioRoutingUtils() {
375         throw new UnsupportedOperationException("CoreAudioRoutingUtils class is non instantiable");
376     }
377 
getVolumeGroups()378     public static List<AudioVolumeGroup> getVolumeGroups() {
379         return VOLUME_GROUPS;
380     }
381 
getProductStrategies()382     public static List<AudioProductStrategy> getProductStrategies() {
383         return PRODUCT_STRATEGIES;
384     }
385 
getCarAudioContextInfos()386     public static List<CarAudioContextInfo> getCarAudioContextInfos() {
387         List<CarAudioContextInfo> carAudioContextInfos = new ArrayList<>(3);
388 
389         carAudioContextInfos.add(MEDIA_CONTEXT_INFO);
390         carAudioContextInfos.add(NAV_CONTEXT_INFO);
391         carAudioContextInfos.add(OEM_CONTEXT_INFO);
392 
393         return carAudioContextInfos;
394     }
395 
396     /**
397      * Returns a car audio control context built using core routing management
398      */
getCoreCarAudioContext()399     public static CarAudioContext getCoreCarAudioContext() {
400         return new CarAudioContext(getCarAudioContextInfos(), true);
401     }
402 
403     /**
404      * Returns an audio control HAL context built using core routing management
405      */
createCoreHALAudioContext()406     public static AudioZoneContext createCoreHALAudioContext() {
407         android.media.audio.common.AudioAttributes oemAttributes =
408                 new android.media.audio.common.AudioAttributes();
409         oemAttributes.usage = AudioUsage.ASSISTANCE_NAVIGATION_GUIDANCE;
410         oemAttributes.contentType = AudioContentType.SPEECH;
411         oemAttributes.tags = new String[]{OEM_FORMATTED_TAGS};
412 
413         AudioZoneContextInfo oemInfo = new AudioZoneContextInfo();
414         oemInfo.id = OEM_STRATEGY_ID;
415         oemInfo.name = OEM_CONTEXT_NAME;
416         oemInfo.audioAttributes = List.of(oemAttributes);
417 
418         android.media.audio.common.AudioAttributes navAttributes =
419                 new android.media.audio.common.AudioAttributes();
420         navAttributes.usage = AudioUsage.ASSISTANCE_NAVIGATION_GUIDANCE;
421         navAttributes.contentType = AudioContentType.SPEECH;
422         AudioZoneContextInfo navInfo = new AudioZoneContextInfo();
423         navInfo.id = NAV_STRATEGY_ID;
424         navInfo.name = NAV_CONTEXT_NAME;
425         navInfo.audioAttributes = List.of(navAttributes);
426 
427         android.media.audio.common.AudioAttributes musicAttributes =
428                 new android.media.audio.common.AudioAttributes();
429         musicAttributes.usage = AudioUsage.MEDIA;
430         musicAttributes.contentType = AudioContentType.MUSIC;
431         android.media.audio.common.AudioAttributes movieAttributes =
432                 new android.media.audio.common.AudioAttributes();
433         movieAttributes.contentType = AudioContentType.MOVIE;
434         AudioZoneContextInfo musicInfo = new AudioZoneContextInfo();
435         musicInfo.id = MUSIC_STRATEGY_ID;
436         musicInfo.name = MUSIC_CONTEXT_NAME;
437         var audioAttributes = new ArrayList<android.media.audio.common.AudioAttributes>();
438         audioAttributes.add(musicAttributes);
439         audioAttributes.add(movieAttributes);
440         audioAttributes.addAll(createListOfHALAudioAttributes(new int[]{NOTIFICATION,
441                 NOTIFICATION_EVENT, ASSISTANCE_SONIFICATION, ALARM, VOICE_COMMUNICATION,
442                 CALL_ASSISTANT, VOICE_COMMUNICATION_SIGNALLING, NOTIFICATION_TELEPHONY_RINGTONE,
443                 UNKNOWN, GAME, MEDIA, ASSISTANCE_ACCESSIBILITY, ASSISTANT, EMERGENCY, SAFETY,
444                 VEHICLE_STATUS, ANNOUNCEMENT}));
445         musicInfo.audioAttributes = audioAttributes;
446 
447         AudioZoneContext context = new AudioZoneContext();
448         context.audioContextInfos = List.of(musicInfo, navInfo, oemInfo);
449         return context;
450     }
451 
452     /**
453      * @return zone created with core audio contexts
454      */
getCoreAudioZone()455     public static AudioZone getCoreAudioZone() {
456         var coreZone = new AudioZone();
457         coreZone.name = CORE_PRIMARY_ZONE;
458         coreZone.id = AudioHalProductStrategy.ZoneId.DEFAULT;
459         coreZone.audioZoneContext = createCoreHALAudioContext();
460         coreZone.audioZoneConfigs = createCoreAudioZoneConfigs();
461         return coreZone;
462     }
463 
createCoreAudioZoneConfigs()464     private static List<AudioZoneConfig> createCoreAudioZoneConfigs() {
465         var configs = new ArrayList<AudioZoneConfig>(1);
466         configs.add(createCoreAudioZoneConfig());
467         return configs;
468     }
469 
createCoreAudioZoneConfig()470     private static AudioZoneConfig createCoreAudioZoneConfig() {
471         var config = new AudioZoneConfig();
472         config.name = "Core audio zone config";
473         config.isDefault = true;
474         config.volumeGroups = createCoreVolumeGroups();
475         return config;
476     }
477 
createCoreVolumeGroups()478     private static List<VolumeGroupConfig> createCoreVolumeGroups() {
479         var coreOemConfig = getVolumeGroupConfig(createOemCoreAudioRoutes(), OEM_GROUP_NAME,
480                 OEM_GROUP_ID);
481         var coreNavConfig = getVolumeGroupConfig(createNavCoreAudioRoutes(), NAV_GROUP_NAME,
482                 NAV_GROUP_ID);
483         var coreMediaConfig = getVolumeGroupConfig(createMediaCoreAudioRoutes(), MUSIC_GROUP_NAME,
484                 MUSIC_GROUP_ID);
485         return List.of(coreMediaConfig, coreNavConfig, coreOemConfig);
486     }
487 
getVolumeGroupConfig(List<DeviceToContextEntry> contextEntries, String navGroupName, int navGroupId)488     private static VolumeGroupConfig getVolumeGroupConfig(List<DeviceToContextEntry> contextEntries,
489             String navGroupName, int navGroupId) {
490         var coreNavConfig = new VolumeGroupConfig();
491         coreNavConfig.activationConfiguration =
492                 createVolumeActivationConfiguration(TEST_ACTIVATION, TEST_MIN_ACTIVATION,
493                         TEST_MAX_ACTIVATION, ON_BOOT);
494         coreNavConfig.carAudioRoutes = contextEntries;
495         coreNavConfig.name = navGroupName;
496         coreNavConfig.id = navGroupId;
497         return coreNavConfig;
498     }
499 
createMediaCoreAudioRoutes()500     private static List<DeviceToContextEntry> createMediaCoreAudioRoutes() {
501         var busPortDevice = createBusAudioPort(MEDIA_TEST_DEVICE, TEST_MEDIA_PORT_ID,
502                 "core_media_port");
503         var mediaContext = createDeviceToContextEntry(busPortDevice, List.of(MUSIC_CONTEXT_NAME));
504         return List.of(mediaContext);
505     }
506 
createNavCoreAudioRoutes()507     private static List<DeviceToContextEntry> createNavCoreAudioRoutes() {
508         var navPortDevice = createBusAudioPort(NAVIGATION_TEST_DEVICE, TEST_NAVIGATION_PORT_ID,
509                 "core_nav_port");
510         var navContext = createDeviceToContextEntry(navPortDevice, List.of(NAV_CONTEXT_NAME));
511         return List.of(navContext);
512     }
513 
createOemCoreAudioRoutes()514     private static List<DeviceToContextEntry> createOemCoreAudioRoutes() {
515         var oemPortDevice = createBusAudioPort(OEM_TEST_DEVICE, TEST_OEM_PORT_ID,
516                 "core_oem_port");
517         var oemContext = createDeviceToContextEntry(oemPortDevice, List.of(OEM_CONTEXT_NAME));
518         return List.of(oemContext);
519     }
520 }
521