• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 package com.android.car.audio;
17 
18 import static android.hardware.automotive.audiocontrol.VolumeInvocationType.ON_BOOT;
19 import static android.media.AudioAttributes.CONTENT_TYPE_SPEECH;
20 import static android.media.AudioAttributes.USAGE_ALARM;
21 import static android.media.AudioAttributes.USAGE_ANNOUNCEMENT;
22 import static android.media.AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
23 import static android.media.AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
24 import static android.media.AudioAttributes.USAGE_ASSISTANT;
25 import static android.media.AudioAttributes.USAGE_CALL_ASSISTANT;
26 import static android.media.AudioAttributes.USAGE_EMERGENCY;
27 import static android.media.AudioAttributes.USAGE_GAME;
28 import static android.media.AudioAttributes.USAGE_MEDIA;
29 import static android.media.AudioAttributes.USAGE_NOTIFICATION;
30 import static android.media.AudioAttributes.USAGE_NOTIFICATION_EVENT;
31 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
32 import static android.media.AudioAttributes.USAGE_SAFETY;
33 import static android.media.AudioAttributes.USAGE_UNKNOWN;
34 import static android.media.AudioAttributes.USAGE_VEHICLE_STATUS;
35 import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION;
36 import static android.media.audio.common.AudioUsage.ALARM;
37 import static android.media.audio.common.AudioUsage.ANNOUNCEMENT;
38 import static android.media.audio.common.AudioUsage.ASSISTANCE_ACCESSIBILITY;
39 import static android.media.audio.common.AudioUsage.ASSISTANCE_NAVIGATION_GUIDANCE;
40 import static android.media.audio.common.AudioUsage.ASSISTANCE_SONIFICATION;
41 import static android.media.audio.common.AudioUsage.ASSISTANT;
42 import static android.media.audio.common.AudioUsage.CALL_ASSISTANT;
43 import static android.media.audio.common.AudioUsage.EMERGENCY;
44 import static android.media.audio.common.AudioUsage.GAME;
45 import static android.media.audio.common.AudioUsage.MEDIA;
46 import static android.media.audio.common.AudioUsage.NOTIFICATION;
47 import static android.media.audio.common.AudioUsage.NOTIFICATION_EVENT;
48 import static android.media.audio.common.AudioUsage.NOTIFICATION_TELEPHONY_RINGTONE;
49 import static android.media.audio.common.AudioUsage.SAFETY;
50 import static android.media.audio.common.AudioUsage.UNKNOWN;
51 import static android.media.audio.common.AudioUsage.VEHICLE_STATUS;
52 import static android.media.audio.common.AudioUsage.VOICE_COMMUNICATION;
53 import static android.media.audio.common.AudioUsage.VOICE_COMMUNICATION_SIGNALLING;
54 
55 import static com.android.car.audio.CarAudioContext.getAudioAttributeFromUsage;
56 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.ALARM_TEST_DEVICE;
57 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.CALL_TEST_DEVICE;
58 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.MEDIA_TEST_DEVICE;
59 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.NAVIGATION_TEST_DEVICE;
60 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.NOTIFICATION_TEST_DEVICE;
61 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.QUATERNARY_TEST_DEVICE_1;
62 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.RING_TEST_DEVICE;
63 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.SECONDARY_TEST_DEVICE_CONFIG_0;
64 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.SECONDARY_TEST_DEVICE_CONFIG_1_0;
65 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.SECONDARY_TEST_DEVICE_CONFIG_1_1;
66 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.SYSTEM_BUS_DEVICE;
67 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.TERTIARY_TEST_DEVICE_1;
68 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.TERTIARY_TEST_DEVICE_2;
69 import static com.android.car.audio.CarAudioDeviceInfoTestUtils.VOICE_TEST_DEVICE;
70 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
71 
72 import android.car.builtin.media.AudioManagerHelper;
73 import android.car.oem.CarAudioFadeConfiguration;
74 import android.hardware.automotive.audiocontrol.AudioFadeConfiguration;
75 import android.hardware.automotive.audiocontrol.AudioZone;
76 import android.hardware.automotive.audiocontrol.AudioZoneConfig;
77 import android.hardware.automotive.audiocontrol.AudioZoneContext;
78 import android.hardware.automotive.audiocontrol.AudioZoneContextInfo;
79 import android.hardware.automotive.audiocontrol.AudioZoneFadeConfiguration;
80 import android.hardware.automotive.audiocontrol.DeviceToContextEntry;
81 import android.hardware.automotive.audiocontrol.FadeConfiguration;
82 import android.hardware.automotive.audiocontrol.FadeState;
83 import android.hardware.automotive.audiocontrol.TransientFadeConfigurationEntry;
84 import android.hardware.automotive.audiocontrol.VolumeActivationConfiguration;
85 import android.hardware.automotive.audiocontrol.VolumeActivationConfigurationEntry;
86 import android.hardware.automotive.audiocontrol.VolumeGroupConfig;
87 import android.media.AudioAttributes;
88 import android.media.AudioFocusInfo;
89 import android.media.AudioManager;
90 import android.media.FadeManagerConfiguration;
91 import android.media.MediaRecorder;
92 import android.media.audio.common.AudioContentType;
93 import android.media.audio.common.AudioDevice;
94 import android.media.audio.common.AudioDeviceAddress;
95 import android.media.audio.common.AudioDeviceDescription;
96 import android.media.audio.common.AudioDeviceType;
97 import android.media.audio.common.AudioFlag;
98 import android.media.audio.common.AudioGain;
99 import android.media.audio.common.AudioGainMode;
100 import android.media.audio.common.AudioHalProductStrategy;
101 import android.media.audio.common.AudioPort;
102 import android.media.audio.common.AudioPortDeviceExt;
103 import android.media.audio.common.AudioPortExt;
104 import android.media.audio.common.AudioSource;
105 import android.media.audio.common.AudioUsage;
106 import android.os.Build;
107 import android.util.ArrayMap;
108 
109 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
110 
111 import java.util.ArrayList;
112 import java.util.List;
113 
114 
115 @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
116 public final class CarAudioTestUtils {
117 
118     private static final String PACKAGE_NAME = "com.android.car.audio";
119     private static final int AUDIOFOCUS_FLAG = 0;
120 
121     public static final AudioAttributes TEST_UNKNOWN_USAGE_ATTRIBUTE =
122             getAudioAttributeFromUsage(USAGE_UNKNOWN);
123     public static final AudioAttributes TEST_GAME_USAGE_ATTRIBUTE =
124             getAudioAttributeFromUsage(USAGE_GAME);
125     public static final AudioAttributes TEST_CALL_ATTRIBUTE =
126             getAudioAttributeFromUsage(USAGE_VOICE_COMMUNICATION);
127     public static final AudioAttributes TEST_RINGER_ATTRIBUTE =
128             getAudioAttributeFromUsage(USAGE_NOTIFICATION_RINGTONE);
129     public static final AudioAttributes TEST_MEDIA_ATTRIBUTE =
130             getAudioAttributeFromUsage(USAGE_MEDIA);
131     public static final AudioAttributes TEST_EMERGENCY_ATTRIBUTE =
132             getAudioAttributeFromUsage(USAGE_EMERGENCY);
133     public static final AudioAttributes TEST_INVALID_ATTRIBUTE =
134             getAudioAttributeFromUsage(AudioManagerHelper
135                     .getUsageVirtualSource());
136     public static final AudioAttributes TEST_NAVIGATION_ATTRIBUTE =
137             getAudioAttributeFromUsage(
138                     USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
139     public static final AudioAttributes TEST_ASSISTANT_ATTRIBUTE =
140             getAudioAttributeFromUsage(USAGE_ASSISTANT);
141     public static final AudioAttributes TEST_ALARM_ATTRIBUTE =
142             getAudioAttributeFromUsage(USAGE_ALARM);
143     public static final AudioAttributes TEST_NOTIFICATION_ATTRIBUTE =
144             getAudioAttributeFromUsage(USAGE_NOTIFICATION);
145     public static final AudioAttributes TEST_SYSTEM_ATTRIBUTE =
146             getAudioAttributeFromUsage(USAGE_ASSISTANCE_SONIFICATION);
147     public static final AudioAttributes TEST_VEHICLE_ATTRIBUTE =
148             getAudioAttributeFromUsage(USAGE_VEHICLE_STATUS);
149     public static final AudioAttributes TEST_ANNOUNCEMENT_ATTRIBUTE =
150             getAudioAttributeFromUsage(USAGE_ANNOUNCEMENT);
151     public static final AudioAttributes TEST_SAFETY_ATTRIBUTE =
152             getAudioAttributeFromUsage(USAGE_SAFETY);
153     public static final AudioAttributes TEST_NOTIFICATION_EVENT_ATTRIBUTE =
154             getAudioAttributeFromUsage(USAGE_NOTIFICATION_EVENT);
155 
156     public static final String TEST_ACTIVATION = "Test Activation";
157     public static final int TEST_MIN_ACTIVATION = 10;
158     public static final int TEST_MAX_ACTIVATION = 90;
159 
160     private static final CarAudioContextInfo TEST_CONTEXT_INFO_MUSIC =
161             new CarAudioContextInfo(new AudioAttributes[] {
162                     getAudioAttributeFromUsage(AudioAttributes.USAGE_UNKNOWN),
163                     getAudioAttributeFromUsage(AudioAttributes.USAGE_GAME),
164                     getAudioAttributeFromUsage(AudioAttributes.USAGE_MEDIA)
165             }, "MUSIC", 1);
166 
167     private static final CarAudioContextInfo TEST_CONTEXT_INFO_NAVIGATION =
168             new CarAudioContextInfo(new AudioAttributes[] {
169                     getAudioAttributeFromUsage(AudioAttributes
170                             .USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
171             }, "NAVIGATION", 2);
172 
173     private static final CarAudioContextInfo TEST_CONTEXT_INFO_VOICE_COMMAND =
174             new CarAudioContextInfo(new AudioAttributes[] {
175                     getAudioAttributeFromUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY),
176                     getAudioAttributeFromUsage(AudioAttributes.USAGE_ASSISTANT)
177             }, "VOICE_COMMAND", 3);
178 
179     private static final CarAudioContextInfo TEST_CONTEXT_INFO_CALL_RING =
180             new CarAudioContextInfo(new AudioAttributes[] {
181                     getAudioAttributeFromUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
182             }, "CALL_RING", 4);
183 
184     private static final CarAudioContextInfo TEST_CONTEXT_INFO_CALL =
185             new CarAudioContextInfo(new AudioAttributes[] {
186                     getAudioAttributeFromUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION),
187                     getAudioAttributeFromUsage(AudioAttributes.USAGE_CALL_ASSISTANT),
188                     getAudioAttributeFromUsage(AudioAttributes
189                             .USAGE_VOICE_COMMUNICATION_SIGNALLING),
190             }, "CALL", 5);
191 
192     private static final CarAudioContextInfo TEST_CONTEXT_INFO_ALARM =
193             new CarAudioContextInfo(new AudioAttributes[]{
194                     getAudioAttributeFromUsage(AudioAttributes.USAGE_ALARM)
195             }, "ALARM", 6);
196 
197     private static final CarAudioContextInfo TEST_CONTEXT_INFO_NOTIFICATION =
198             new CarAudioContextInfo(new AudioAttributes[]{
199                     getAudioAttributeFromUsage(AudioAttributes.USAGE_NOTIFICATION),
200                     getAudioAttributeFromUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT)
201             }, "NOTIFICATION", 7);
202 
203     private static final CarAudioContextInfo TEST_CONTEXT_INFO_SYSTEM_SOUND =
204             new CarAudioContextInfo(new AudioAttributes[]{
205                     getAudioAttributeFromUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
206             }, "SYSTEM_SOUND", 8);
207 
208     private static final CarAudioContextInfo TEST_CONTEXT_INFO_EMERGENCY =
209             new CarAudioContextInfo(new AudioAttributes[]{
210                     getAudioAttributeFromUsage(AudioAttributes.USAGE_EMERGENCY)
211             }, "EMERGENCY", 9);
212 
213     private static final CarAudioContextInfo TEST_CONTEXT_INFO_SAFETY =
214             new CarAudioContextInfo(new AudioAttributes[]{
215                     getAudioAttributeFromUsage(AudioAttributes.USAGE_SAFETY)
216             }, "SAFETY", 10);
217 
218     private static final CarAudioContextInfo TEST_CONTEXT_INFO_VEHICLE_STATUS =
219             new CarAudioContextInfo(new AudioAttributes[]{
220                     getAudioAttributeFromUsage(AudioAttributes.USAGE_VEHICLE_STATUS)
221             }, "VEHICLE_STATUS", 11);
222 
223     private static final CarAudioContextInfo TEST_CONTEXT_INFO_ANNOUNCEMENT =
224             new CarAudioContextInfo(new AudioAttributes[]{
225                     getAudioAttributeFromUsage(AudioAttributes.USAGE_ANNOUNCEMENT)
226             }, "ANNOUNCEMENT", 12);
227 
228     private static final long TEST_FADE_IN_DURATION_MS = 200L;
229     private static final long TEST_FADE_OUT_DURATION_MS = 300L;
230     private static final long TEST_FADE_IN_DELAYED_FOR_OFFENDERS_MS = 3_000L;
231     private static final long TEST_FADE_OUT_CONFIG_DURATION_MS = 800L;
232     private static final long TEST_FADE_IN_CONFIG_DURATION_MS = 0L;
233 
234     public static final CarAudioContext TEST_CREATED_CAR_AUDIO_CONTEXT =
235             new CarAudioContext(List.of(TEST_CONTEXT_INFO_MUSIC, TEST_CONTEXT_INFO_NAVIGATION,
236                     TEST_CONTEXT_INFO_VOICE_COMMAND, TEST_CONTEXT_INFO_CALL_RING,
237                     TEST_CONTEXT_INFO_CALL, TEST_CONTEXT_INFO_ALARM, TEST_CONTEXT_INFO_NOTIFICATION,
238                     TEST_CONTEXT_INFO_SYSTEM_SOUND, TEST_CONTEXT_INFO_EMERGENCY,
239                     TEST_CONTEXT_INFO_SAFETY, TEST_CONTEXT_INFO_VEHICLE_STATUS,
240                     TEST_CONTEXT_INFO_ANNOUNCEMENT),
241                     /* useCoreAudioRouting= */ false);
242 
243     public static final CarAudioContext TEST_CAR_AUDIO_CONTEXT =
244             new CarAudioContext(CarAudioContext.getAllContextsInfo(),
245                     /* useCoreAudioRouting= */ false);
246 
247     static final String MUSIC_CONTEXT = "MUSIC";
248     static final String NAVIGATION_CONTEXT = "NAVIGATION";
249     static final String VOICE_COMMAND_CONTEXT = "VOICE_COMMAND";
250     static final String RING_CONTEXT = "CALL_RING";
251     static final String NOTIFICATION_CONTEXT = "NOTIFICATION";
252     static final String INVALID_CONTEXT_NAME = "no context name";
253     static final int MUSIC_CONTEXT_ID = 1;
254     static final int NAVIGATION_CONTEXT_ID = 2;
255     static final int VOICE_COMMAND_CONTEXT_ID = 3;
256     static final int RING_CONTEXT_ID = 4;
257     static final int NOTIFICATION_CONTEXT_ID = 7;
258 
259     static final AudioGain[] GAINS = new AudioGain[] {
260             new AudioGain() {{
261                 mode = AudioGainMode.JOINT;
262                 minValue = 0;
263                 maxValue = 100;
264                 defaultValue = 50;
265                 stepValue = 2;
266             }}
267     };
268     public static final String ANNOUNCEMENT_CONTEXT = "ANNOUNCEMENT";
269     public static final int ANNOUNCEMENT_CONTEXT_ID = 12;
270     public static final String CALL_CONTEXT = "CALL";
271     public static final int CALL_CONTEXT_ID = 5;
272     public static final String ALARM_CONTEXT = "ALARM";
273     public static final int ALARM_CONTEXT_ID = 6;
274     public static final String SYSTEM_CONTEXT = "SYSTEM_SOUND";
275     public static final int SYSTEM_CONTEXT_ID = 8;
276     public static final String EMERGENCY_CONTEXT = "EMERGENCY";
277     public static final int EMERGENCY_CONTEXT_ID = 9;
278     public static final String SAFETY_CONTEXT = "SAFETY";
279     public static final int SAFETY_CONTEXT_ID = 10;
280     public static final String VEHICLE_STATUS_CONTEXT = "VEHICLE_STATUS";
281     public static final int VEHICLE_STATUS_CONTEXT_ID = 11;
282 
283     public static final String PRIMARY_ZONE_NAME = "primary zone";
284     public static final int PRIMARY_OCCUPANT_ID = 1;
285     public static final String PRIMARY_ZONE_CONFIG_1 = "primary zone config 1";
286     public static final String BLUETOOTH_ZONE_CONFIG_1 = "bluetooth zone config 1";
287     public static final String USB_ZONE_CONFIG_1 = "USB zone config 1";
288 
289     public static final String SECONDARY_ZONE_NAME = "secondary zone";
290     public static final int SECONDARY_ZONE_ID = AudioHalProductStrategy.ZoneId.DEFAULT + 1;
291     public static final int SECONDARY_OCCUPANT_ID = 2;
292 
293     public static final String SECONDARY_ZONE_CONFIG_NAME_1 = "secondary zone config 1";
294     public static final int SECONDARY_ZONE_VOLUME_GROUP_COUNT = 1;
295 
296     public static final int SECONDARY_ZONE_VOLUME_GROUP_ID = SECONDARY_ZONE_VOLUME_GROUP_COUNT - 1;
297     public static final String SECONDARY_ZONE_CONFIG_NAME_2 = "secondary zone config 2";
298     public static final int TEST_SECONDARY_ZONE_GROUP_0 = 0;
299     public static final int TEST_SECONDARY_ZONE_GROUP_1 = 1;
300 
301     public static final String TERTIARY_ZONE_NAME = "tertiary zone";
302     public static final int TERTIARY_OCCUPANT_ID = 3;
303     public static final int TERTIARY_ZONE_ID = AudioHalProductStrategy.ZoneId.DEFAULT + 2;
304     private static final int TERTIARY_ZONE_VOLUME_GROUP_ID = 0;
305     public static final String TERTIARY_ZONE_CONFIG_NAME_1 = "tertiary zone config 1";
306     public static final String TERTIARY_ZONE_CONFIG_NAME_2 = "tertiary zone config 2";
307 
308     public static final String QUATERNARY_ZONE_NAME = "tertiary zone";
309     public static final int QUATERNARY_OCCUPANT_ID = 4;
310     public static final int QUATERNARY_ZONE_ID = AudioHalProductStrategy.ZoneId.DEFAULT + 3;
311     private static final int QUATERNARY_ZONE_VOLUME_GROUP_ID = 0;
312     public static final String QUATERNARY_ZONE_CONFIG_NAME_1 = "tertiary zone config 1";
313 
314     static final int MEDIA_VOLUME_GROUP_ID = 0;
315     static final String MEDIA_VOLUME_NAME = "media_volume";
316     static final int NAVIGATION_AND_VOICE_VOLUME_GROUP_ID = 1;
317     static final String NAVIGATION_AND_VOICE_VOLUME_NAME = "navigation_voice_volume";
318     static final int TELEPHONY_VOLUME_GROUP_ID = 2;
319     static final String TELEPHONY_VOLUME_NAME = "telephony_volume";
320     static final int SYSTEM_VOLUME_GROUP_ID = 3;
321 
322     static final int TEST_FLAGS = AudioFlag.AUDIBILITY_ENFORCED;
323     static final String[] TEST_TAGS =  {"OEM_NAV", "OEM_ASSISTANT"};
324     static final String TEST_FADE_CONFIGURATION_NAME = "Test fade configuration";
325 
CarAudioTestUtils()326     private CarAudioTestUtils() {
327         throw new UnsupportedOperationException();
328     }
329 
getInfo(AudioAttributes audioAttributes, String clientId, int gainType, boolean acceptsDelayedFocus, boolean pauseInsteadOfDucking, int uid)330     static AudioFocusInfo getInfo(AudioAttributes audioAttributes, String clientId, int gainType,
331             boolean acceptsDelayedFocus, boolean pauseInsteadOfDucking, int uid) {
332         int flags = AUDIOFOCUS_FLAG;
333         if (acceptsDelayedFocus) {
334             flags |= AudioManager.AUDIOFOCUS_FLAG_DELAY_OK;
335         }
336         if (pauseInsteadOfDucking) {
337             flags |= AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
338         }
339         return new AudioFocusInfo(audioAttributes, uid, clientId, PACKAGE_NAME,
340                 gainType, AudioManager.AUDIOFOCUS_NONE,
341                 flags, Build.VERSION.SDK_INT);
342     }
343 
344     /**
345      * Creates an external audio port device
346      *
347      * @param type Type of audio device (e.g. BUS)
348      * @param connection Connection for the audio device
349      * @param address Device address
350      * @return Created audio device
351      */
createAudioPortDeviceExt(int type, String connection, String address)352     public static AudioPortDeviceExt createAudioPortDeviceExt(int type, String connection,
353                                                               String address) {
354         AudioPortDeviceExt deviceExt = new AudioPortDeviceExt();
355         deviceExt.device = new AudioDevice();
356         deviceExt.device.type = new AudioDeviceDescription();
357         deviceExt.device.type.type = type;
358         deviceExt.device.type.connection = connection;
359         deviceExt.device.address = AudioDeviceAddress.id(address);
360         return deviceExt;
361     }
362 
363     /**
364      * Creates an audio port for testing
365      *
366      * @param id ID of the audio port device
367      * @param name Name of the audio port
368      * @param gains Gains of the audio port
369      * @param deviceExt External device represented by the port
370      *
371      * @return Created audio device port
372      */
createAudioPort(int id, String name, AudioGain[] gains, AudioPortDeviceExt deviceExt)373     public static AudioPort createAudioPort(int id, String name, AudioGain[] gains,
374                                             AudioPortDeviceExt deviceExt) {
375         AudioPort audioPort = new AudioPort();
376         audioPort.id = id;
377         audioPort.name = name;
378         audioPort.gains = gains;
379         audioPort.ext = AudioPortExt.device(deviceExt);
380         return audioPort;
381     }
382 
createHALAudioContext()383     static AudioZoneContext createHALAudioContext() {
384         AudioZoneContext context = new AudioZoneContext();
385         context.audioContextInfos = new ArrayList<>();
386         context.audioContextInfos.add(createAudioZoneContextInfo(new int[]{UNKNOWN, GAME, MEDIA},
387                 MUSIC_CONTEXT, MUSIC_CONTEXT_ID));
388         context.audioContextInfos.add(createAudioZoneContextInfo(
389                 new int[]{ASSISTANCE_NAVIGATION_GUIDANCE}, NAVIGATION_CONTEXT,
390                 NAVIGATION_CONTEXT_ID));
391         context.audioContextInfos.add(createAudioZoneContextInfo(
392                 new int[]{ASSISTANCE_ACCESSIBILITY, ASSISTANT}, VOICE_COMMAND_CONTEXT,
393                 VOICE_COMMAND_CONTEXT_ID));
394         context.audioContextInfos.add(createAudioZoneContextInfo(
395                 new int[]{NOTIFICATION_TELEPHONY_RINGTONE}, RING_CONTEXT, RING_CONTEXT_ID));
396         context.audioContextInfos.add(createAudioZoneContextInfo(
397                 new int[]{VOICE_COMMUNICATION, CALL_ASSISTANT, VOICE_COMMUNICATION_SIGNALLING},
398                 CALL_CONTEXT, CALL_CONTEXT_ID));
399         context.audioContextInfos.add(createAudioZoneContextInfo(new int[]{ALARM}, ALARM_CONTEXT,
400                 ALARM_CONTEXT_ID));
401         context.audioContextInfos.add(createAudioZoneContextInfo(
402                 new int[]{NOTIFICATION, NOTIFICATION_EVENT}, NOTIFICATION_CONTEXT,
403                 NOTIFICATION_CONTEXT_ID));
404         context.audioContextInfos.add(createAudioZoneContextInfo(
405                 new int[]{ASSISTANCE_SONIFICATION}, SYSTEM_CONTEXT, SYSTEM_CONTEXT_ID));
406         context.audioContextInfos.add(createAudioZoneContextInfo(
407                 new int[]{EMERGENCY}, EMERGENCY_CONTEXT, EMERGENCY_CONTEXT_ID));
408         context.audioContextInfos.add(createAudioZoneContextInfo(
409                 new int[]{SAFETY}, SAFETY_CONTEXT, SAFETY_CONTEXT_ID));
410         context.audioContextInfos.add(createAudioZoneContextInfo(
411                 new int[]{VEHICLE_STATUS}, VEHICLE_STATUS_CONTEXT, VEHICLE_STATUS_CONTEXT_ID));
412         context.audioContextInfos.add(createAudioZoneContextInfo(
413                 new int[]{ANNOUNCEMENT}, ANNOUNCEMENT_CONTEXT, ANNOUNCEMENT_CONTEXT_ID));
414         return context;
415     }
416 
createDefaultAudioZoneConfig()417     static AudioZoneConfig createDefaultAudioZoneConfig() {
418         var mediaBusPort = createBusAudioPort(MEDIA_TEST_DEVICE, 10, "media_port");
419         var mediaBusContextEntry = createDeviceToContextEntry(mediaBusPort,
420                 List.of(MUSIC_CONTEXT, ANNOUNCEMENT_CONTEXT));
421         var notificationBusPort = createBusAudioPort(NOTIFICATION_TEST_DEVICE, 11,
422                 "notification_port");
423         var notificationBusContextEntry = createDeviceToContextEntry(notificationBusPort,
424                 List.of(NOTIFICATION_CONTEXT));
425         var mediaVolume = createVolumeGroupConfig(MEDIA_VOLUME_GROUP_ID, MEDIA_VOLUME_NAME,
426                 List.of(mediaBusContextEntry, notificationBusContextEntry));
427 
428         return getAudioZoneConfig(List.of(mediaVolume, getNavAndVoiceVolumeGroupConfig(),
429                 getTelephonyVolumeGroupConfig(), getSystemVolumeGroupConfig()),
430                 /* isDefault= */ true, PRIMARY_ZONE_CONFIG_1);
431     }
432 
createBluetoothAudioZoneConfig()433     static AudioZoneConfig createBluetoothAudioZoneConfig() {
434         var btPortDevice = createAudioPortDeviceExt(AudioDeviceType.OUT_HEADPHONE,
435                 AudioDeviceDescription.CONNECTION_BT_A2DP, /* address= */ "");
436         var btAudioPort = createAudioPort(10, /* name= */ "", GAINS, btPortDevice);
437         var mediaBTContextEntry = createDeviceToContextEntry(btAudioPort,
438                 List.of(MUSIC_CONTEXT, ANNOUNCEMENT_CONTEXT, NOTIFICATION_CONTEXT));
439         var mediaVolume = createVolumeGroupConfig(MEDIA_VOLUME_GROUP_ID, MEDIA_VOLUME_NAME,
440                 List.of(mediaBTContextEntry));
441 
442         return getAudioZoneConfig(List.of(mediaVolume, getNavAndVoiceVolumeGroupConfig(),
443                 getTelephonyVolumeGroupConfig(), getSystemVolumeGroupConfig()),
444                 /* isDefault= */ false, BLUETOOTH_ZONE_CONFIG_1);
445     }
446 
createUSBAudioZoneConfig()447     static AudioZoneConfig createUSBAudioZoneConfig() {
448         var btPortDevice = createAudioPortDeviceExt(AudioDeviceType.OUT_HEADPHONE,
449                 AudioDeviceDescription.CONNECTION_USB, /* address= */ "");
450         var btAudioPort = createAudioPort(10, /* name= */ "", GAINS, btPortDevice);
451         var mediaBTContextEntry = createDeviceToContextEntry(btAudioPort,
452                 List.of(MUSIC_CONTEXT, ANNOUNCEMENT_CONTEXT, NOTIFICATION_CONTEXT));
453         var mediaVolume = createVolumeGroupConfig(MEDIA_VOLUME_GROUP_ID, MEDIA_VOLUME_NAME,
454                 List.of(mediaBTContextEntry));
455 
456         return getAudioZoneConfig(List.of(mediaVolume, getNavAndVoiceVolumeGroupConfig(),
457                         getTelephonyVolumeGroupConfig(), getSystemVolumeGroupConfig()),
458                 /* isDefault= */ false, USB_ZONE_CONFIG_1);
459     }
460 
getSystemVolumeGroupConfig()461     private static VolumeGroupConfig getSystemVolumeGroupConfig() {
462         var alarmBusPort = createBusAudioPort(ALARM_TEST_DEVICE, 17, "alarm_port");
463         var alarmBusContextEntry = createDeviceToContextEntry(alarmBusPort, List.of(ALARM_CONTEXT));
464         var systemBusPort = createBusAudioPort(SYSTEM_BUS_DEVICE, 18, "system_port");
465         var systemBusContextEntry = createDeviceToContextEntry(systemBusPort,
466                 List.of(SYSTEM_CONTEXT, EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT));
467         return createVolumeGroupConfig(SYSTEM_VOLUME_GROUP_ID, /* groupName= */ "",
468                 List.of(alarmBusContextEntry, systemBusContextEntry));
469     }
470 
getTelephonyVolumeGroupConfig()471     private static VolumeGroupConfig getTelephonyVolumeGroupConfig() {
472         var callBusPort = createBusAudioPort(CALL_TEST_DEVICE, 15, "call_port");
473         var callBusContextEntry = createDeviceToContextEntry(callBusPort,
474                 List.of(CALL_CONTEXT));
475         var ringBusPort = createBusAudioPort(RING_TEST_DEVICE, 16, "ring_port");
476         var ringBusContextEntry = createDeviceToContextEntry(ringBusPort, List.of(RING_CONTEXT));
477         return createVolumeGroupConfig(TELEPHONY_VOLUME_GROUP_ID,
478                 TELEPHONY_VOLUME_NAME, List.of(callBusContextEntry, ringBusContextEntry));
479     }
480 
getNavAndVoiceVolumeGroupConfig()481     private static VolumeGroupConfig getNavAndVoiceVolumeGroupConfig() {
482         var navBusPort = createBusAudioPort(NAVIGATION_TEST_DEVICE, 13, "nav_port");
483         var navBusContextEntry = createDeviceToContextEntry(navBusPort,
484                 List.of(NAVIGATION_CONTEXT));
485         var voiceBusPort = createBusAudioPort(VOICE_TEST_DEVICE, 14, "voice_port");
486         var voiceBusContextEntry = createDeviceToContextEntry(voiceBusPort,
487                 List.of(VOICE_COMMAND_CONTEXT));
488         return createVolumeGroupConfig(NAVIGATION_AND_VOICE_VOLUME_GROUP_ID,
489                 NAVIGATION_AND_VOICE_VOLUME_NAME,
490                 List.of(navBusContextEntry, voiceBusContextEntry));
491     }
492 
getAudioZoneConfig(List<VolumeGroupConfig> groups, boolean isDefault, String configName)493     private static AudioZoneConfig getAudioZoneConfig(List<VolumeGroupConfig> groups,
494             boolean isDefault, String configName) {
495         var audioZoneConfig = new AudioZoneConfig();
496         audioZoneConfig.name = configName;
497         audioZoneConfig.isDefault = isDefault;
498         audioZoneConfig.volumeGroups = groups;
499         AudioZoneFadeConfiguration fadeConfiguration = new AudioZoneFadeConfiguration();
500         fadeConfiguration.defaultConfiguration = createTestFadeConfiguration();
501         var configuration = new AudioFadeConfiguration();
502         configuration.fadeState = FadeState.FADE_STATE_DISABLED;
503         var entry = new TransientFadeConfigurationEntry();
504         entry.transientFadeConfiguration = configuration;
505         entry.transientUsages = new int[]{EMERGENCY};
506         fadeConfiguration.transientConfiguration = List.of(entry);
507         audioZoneConfig.fadeConfiguration = fadeConfiguration;
508         return audioZoneConfig;
509     }
510 
createPrimaryAudioZone()511     static AudioZone createPrimaryAudioZone() {
512         var audioZone = new AudioZone();
513         audioZone.id = AudioHalProductStrategy.ZoneId.DEFAULT;
514         audioZone.name = PRIMARY_ZONE_NAME;
515         audioZone.occupantZoneId = 1;
516         audioZone.audioZoneContext = createHALAudioContext();
517         audioZone.audioZoneConfigs = List.of(createDefaultAudioZoneConfig(),
518                 createBluetoothAudioZoneConfig(), createUSBAudioZoneConfig());
519         return audioZone;
520     }
521 
createAudioServiceAudioZones()522     static List<AudioZone> createAudioServiceAudioZones() {
523         var primaryAudioZone = createAudioZones(AudioHalProductStrategy.ZoneId.DEFAULT,
524                 PRIMARY_OCCUPANT_ID, PRIMARY_ZONE_NAME, List.of(createDefaultAudioZoneConfig()));
525         return List.of(primaryAudioZone, createSecondaryAudioZone(), createTertiaryAudioZone(),
526                 createQuarternaryAudioZone());
527     }
528 
createQuarternaryAudioZone()529     private static AudioZone createQuarternaryAudioZone() {
530         return createAudioZones(QUATERNARY_ZONE_ID, QUATERNARY_OCCUPANT_ID, QUATERNARY_ZONE_NAME,
531                 List.of(createDefaultQuaternaryAudioZoneConfig()));
532     }
533 
createDefaultQuaternaryAudioZoneConfig()534     private static AudioZoneConfig createDefaultQuaternaryAudioZoneConfig() {
535         return getAudioZoneConfig(List.of(getQuatenaryDefaultVolumeGroupConfig()),
536                 /* isDefault= */ true, QUATERNARY_ZONE_CONFIG_NAME_1);
537     }
538 
getQuatenaryDefaultVolumeGroupConfig()539     private static VolumeGroupConfig getQuatenaryDefaultVolumeGroupConfig() {
540         var quaternarySecondaryPort = createBusAudioPort(QUATERNARY_TEST_DEVICE_1, 23,
541                 "rear_row_three_zone_bus_1_port");
542         var quateranryBusContextEntry = createDeviceToContextEntry(quaternarySecondaryPort,
543                 List.of(MUSIC_CONTEXT, NAVIGATION_CONTEXT, VOICE_COMMAND_CONTEXT, RING_CONTEXT,
544                         CALL_CONTEXT, ALARM_CONTEXT, SYSTEM_CONTEXT, NOTIFICATION_CONTEXT,
545                         EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT,
546                         ANNOUNCEMENT_CONTEXT));
547         return createVolumeGroupConfig(QUATERNARY_ZONE_VOLUME_GROUP_ID, /* groupName= */ "",
548                 List.of(quateranryBusContextEntry));
549     }
550 
createSecondaryAudioZone()551     static AudioZone createSecondaryAudioZone() {
552         return createAudioZones(SECONDARY_ZONE_ID, SECONDARY_OCCUPANT_ID, SECONDARY_ZONE_NAME,
553                 List.of(createSecondaryDefaultAudioZoneConfig(),
554                         createSecondarySecondAudioZoneConfig()));
555     }
556 
createTertiaryAudioZone()557     private static AudioZone createTertiaryAudioZone() {
558         return createAudioZones(TERTIARY_ZONE_ID, TERTIARY_OCCUPANT_ID, TERTIARY_ZONE_NAME,
559                 List.of(createDefaultTertiaryAudioZoneConfig(),
560                         createSecondTertiaryAudioZoneConfig()));
561     }
562 
createDefaultTertiaryAudioZoneConfig()563     private static AudioZoneConfig createDefaultTertiaryAudioZoneConfig() {
564         return getAudioZoneConfig(List.of(getTertiaryDefaultVolumeGroupConfig()),
565                 /* isDefault= */ true, TERTIARY_ZONE_CONFIG_NAME_1);
566     }
567 
getTertiaryDefaultVolumeGroupConfig()568     private static VolumeGroupConfig getTertiaryDefaultVolumeGroupConfig() {
569         var defaultSecondaryPort = createBusAudioPort(TERTIARY_TEST_DEVICE_1, 22,
570                 "bus_100_port");
571         var tertiaryBusContextEntry = createDeviceToContextEntry(defaultSecondaryPort,
572                 List.of(MUSIC_CONTEXT, NAVIGATION_CONTEXT, VOICE_COMMAND_CONTEXT, RING_CONTEXT,
573                         CALL_CONTEXT, ALARM_CONTEXT, SYSTEM_CONTEXT, NOTIFICATION_CONTEXT,
574                         EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT,
575                         ANNOUNCEMENT_CONTEXT));
576         return createVolumeGroupConfig(TERTIARY_ZONE_VOLUME_GROUP_ID, /* groupName= */ "",
577                 List.of(tertiaryBusContextEntry));
578     }
579 
createSecondTertiaryAudioZoneConfig()580     private static AudioZoneConfig createSecondTertiaryAudioZoneConfig() {
581         return getAudioZoneConfig(List.of(getTertiarySecondaryVolumeGroupConfig()),
582                 /* isDefault= */ false, TERTIARY_ZONE_CONFIG_NAME_2);
583     }
584 
getTertiarySecondaryVolumeGroupConfig()585     private static VolumeGroupConfig getTertiarySecondaryVolumeGroupConfig() {
586         var defaultSecondaryPort = createBusAudioPort(TERTIARY_TEST_DEVICE_2, 23,
587                 "bus_200_port");
588         var tertiaryBusContextEntry = createDeviceToContextEntry(defaultSecondaryPort,
589                 List.of(MUSIC_CONTEXT, NAVIGATION_CONTEXT, VOICE_COMMAND_CONTEXT, RING_CONTEXT,
590                         CALL_CONTEXT, ALARM_CONTEXT, SYSTEM_CONTEXT, NOTIFICATION_CONTEXT,
591                         EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT,
592                         ANNOUNCEMENT_CONTEXT));
593         return createVolumeGroupConfig(TERTIARY_ZONE_VOLUME_GROUP_ID, /* groupName= */ "",
594                 List.of(tertiaryBusContextEntry));
595     }
596 
createAudioZones(int zoneId, int occupantZoneId, String zoneName, List<AudioZoneConfig> zoneConfigs)597     private static AudioZone createAudioZones(int zoneId, int occupantZoneId, String zoneName,
598             List<AudioZoneConfig> zoneConfigs) {
599         var audioZone = new AudioZone();
600         audioZone.id = zoneId;
601         audioZone.name = zoneName;
602         audioZone.occupantZoneId = occupantZoneId;
603         audioZone.audioZoneContext = createHALAudioContext();
604         audioZone.audioZoneConfigs = zoneConfigs;
605         return audioZone;
606     }
607 
createSecondaryDefaultAudioZoneConfig()608     private static AudioZoneConfig createSecondaryDefaultAudioZoneConfig() {
609         return getAudioZoneConfig(List.of(getSecondaryDefaultVolumeGroupConfig()),
610                 /* isDefault= */ true, SECONDARY_ZONE_CONFIG_NAME_1);
611     }
612 
createSecondarySecondAudioZoneConfig()613     private static AudioZoneConfig createSecondarySecondAudioZoneConfig() {
614         return getAudioZoneConfig(List.of(getSecondaryMediaVolumeGroupConfig(),
615                         getSecondarySystemVolumeGroupConfig()),
616                 /* isDefault= */ false, SECONDARY_ZONE_CONFIG_NAME_2);
617     }
618 
getSecondaryMediaVolumeGroupConfig()619     private static VolumeGroupConfig getSecondaryMediaVolumeGroupConfig() {
620         var secondaryMediaPort = createBusAudioPort(SECONDARY_TEST_DEVICE_CONFIG_1_0, 20,
621                 "secondary_port_1");
622         var secondaryMediaBusContextEntry = createDeviceToContextEntry(secondaryMediaPort,
623                 List.of(MUSIC_CONTEXT, ANNOUNCEMENT_CONTEXT, NOTIFICATION_CONTEXT,
624                         NAVIGATION_CONTEXT, VOICE_COMMAND_CONTEXT));
625         return createVolumeGroupConfig(TEST_SECONDARY_ZONE_GROUP_0, /* groupName= */ "",
626                 List.of(secondaryMediaBusContextEntry));
627     }
628 
getSecondarySystemVolumeGroupConfig()629     private static VolumeGroupConfig getSecondarySystemVolumeGroupConfig() {
630         var secondaryMediaPort = createBusAudioPort(SECONDARY_TEST_DEVICE_CONFIG_1_1, 21,
631                 "secondary_port_2");
632         var secondaryMediaBusContextEntry = createDeviceToContextEntry(secondaryMediaPort,
633                 List.of(RING_CONTEXT, CALL_CONTEXT, ALARM_CONTEXT, SYSTEM_CONTEXT,
634                         EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT));
635         return createVolumeGroupConfig(TEST_SECONDARY_ZONE_GROUP_1, /* groupName= */ "",
636                 List.of(secondaryMediaBusContextEntry));
637     }
638 
getSecondaryDefaultVolumeGroupConfig()639     private static VolumeGroupConfig getSecondaryDefaultVolumeGroupConfig() {
640         var defaultSecondaryPort = createBusAudioPort(SECONDARY_TEST_DEVICE_CONFIG_0, 19,
641                 "secondary_port");
642         var defaultSecondaryBusContextEntry = createDeviceToContextEntry(defaultSecondaryPort,
643                 List.of(MUSIC_CONTEXT, NAVIGATION_CONTEXT, VOICE_COMMAND_CONTEXT, RING_CONTEXT,
644                         CALL_CONTEXT, ALARM_CONTEXT, SYSTEM_CONTEXT, NOTIFICATION_CONTEXT,
645                         EMERGENCY_CONTEXT, SAFETY_CONTEXT, VEHICLE_STATUS_CONTEXT,
646                         ANNOUNCEMENT_CONTEXT));
647         return createVolumeGroupConfig(SECONDARY_ZONE_VOLUME_GROUP_ID, /* groupName= */ "",
648                 List.of(defaultSecondaryBusContextEntry));
649     }
650 
createVolumeGroupConfig(int groupId, String groupName, List<DeviceToContextEntry> contextEntries)651     static VolumeGroupConfig createVolumeGroupConfig(int groupId, String groupName,
652             List<DeviceToContextEntry> contextEntries) {
653         var volumeGroupConfig = new VolumeGroupConfig();
654         volumeGroupConfig.id = groupId;
655         volumeGroupConfig.name = groupName;
656         volumeGroupConfig.activationConfiguration =
657                 createVolumeActivationConfiguration(TEST_ACTIVATION, TEST_MIN_ACTIVATION,
658                         TEST_MAX_ACTIVATION, ON_BOOT);
659         volumeGroupConfig.carAudioRoutes = contextEntries;
660         return volumeGroupConfig;
661     }
662 
createVolumeActivationConfiguration(String name, int min, int max, int activation)663     static VolumeActivationConfiguration createVolumeActivationConfiguration(String name,
664             int min, int max, int activation) {
665         VolumeActivationConfiguration configuration = new VolumeActivationConfiguration();
666         configuration.name = name;
667 
668         VolumeActivationConfigurationEntry entry = new VolumeActivationConfigurationEntry();
669         entry.minActivationVolumePercentage = min;
670         entry.maxActivationVolumePercentage = max;
671         entry.type = activation;
672 
673         configuration.volumeActivationEntries = new ArrayList<>(1);
674         configuration.volumeActivationEntries.add(entry);
675 
676         return configuration;
677     }
678 
createBusAudioPort(String portAddress, int portId, String portName)679     static AudioPort createBusAudioPort(String portAddress, int portId, String portName) {
680         var busPortDevice = createAudioPortDeviceExt(AudioDeviceType.OUT_BUS, /* connection= */ "",
681                 portAddress);
682         return createAudioPort(portId, portName, GAINS, busPortDevice);
683     }
684 
createDeviceToContextEntry(AudioPort audioPort, List<String> contextList)685     static DeviceToContextEntry createDeviceToContextEntry(AudioPort audioPort,
686             List<String> contextList) {
687         var entry = new DeviceToContextEntry();
688         entry.device = audioPort;
689         entry.contextNames = new ArrayList<>(contextList);
690         return entry;
691     }
692 
createCarAudioContextNameToIdMap(CarAudioContext context)693     static ArrayMap<String, Integer> createCarAudioContextNameToIdMap(CarAudioContext context) {
694         var contextNameToId = new ArrayMap<String, Integer>(context.getContextsInfo().size());
695         for (int c = 0; c < context.getContextsInfo().size(); c++) {
696             var info = context.getContextsInfo().get(c);
697             contextNameToId.put(info.getName(), info.getId());
698         }
699         return contextNameToId;
700     }
701 
getContextForVolumeGroupConfig(VolumeGroupConfig groupConfig, ArrayMap<String, Integer> contextNameToId)702     static Iterable<Integer> getContextForVolumeGroupConfig(VolumeGroupConfig groupConfig,
703             ArrayMap<String, Integer> contextNameToId)  {
704         var contexts = new ArrayList<Integer>();
705         for (int c = 0; c < groupConfig.carAudioRoutes.size(); c++) {
706             var route = groupConfig.carAudioRoutes.get(c);
707             contexts.addAll(getContextForAudioRoute(route, contextNameToId));
708         }
709         return contexts;
710     }
711 
getContextForAudioRoute(DeviceToContextEntry route, ArrayMap<String, Integer> contextNameToId)712     private static List<Integer> getContextForAudioRoute(DeviceToContextEntry route,
713             ArrayMap<String, Integer> contextNameToId) {
714         var contexts = new ArrayList<Integer>();
715         for (int c = 0; c < route.contextNames.size(); c++) {
716             var name = route.contextNames.get(c);
717             int id = contextNameToId.getOrDefault(name, CarAudioContext.getInvalidContext());
718             contexts.add(id);
719         }
720         return contexts;
721     }
722 
createAudioZoneContextInfo(int[] usages, String name, int id)723     private static AudioZoneContextInfo createAudioZoneContextInfo(int[] usages, String name,
724             int id) {
725         AudioZoneContextInfo info = new AudioZoneContextInfo();
726         info.id = id;
727         info.name = name;
728         info.audioAttributes = createListOfHALAudioAttributes(usages);
729         return info;
730     }
731 
732     static List<android.media.audio.common.AudioAttributes>
createListOfHALAudioAttributes(int[] usages)733             createListOfHALAudioAttributes(int[] usages) {
734         var audioAttributes =
735                 new ArrayList<android.media.audio.common.AudioAttributes>(usages.length);
736         for (int usage : usages) {
737             android.media.audio.common.AudioAttributes
738                     attributes = new android.media.audio.common.AudioAttributes();
739             attributes.usage = usage;
740             audioAttributes.add(attributes);
741         }
742         return audioAttributes;
743     }
744 
createHALAudioAttribute(int usage)745     static android.media.audio.common.AudioAttributes createHALAudioAttribute(int usage) {
746         android.media.audio.common.AudioAttributes
747                 attributes = new android.media.audio.common.AudioAttributes();
748         attributes.usage = usage;
749         attributes.flags = TEST_FLAGS;
750         attributes.tags = TEST_TAGS;
751         attributes.contentType = AudioContentType.MOVIE;
752         attributes.source = AudioSource.CAMCORDER;
753         return attributes;
754     }
755 
createMediaAudioAttributes(int usage)756     static AudioAttributes createMediaAudioAttributes(int usage) {
757         android.media.AudioAttributes.Builder builder = new AudioAttributes.Builder()
758                 .setFlags(TEST_FLAGS)
759                 .setContentType(android.media.AudioAttributes.CONTENT_TYPE_MOVIE)
760                 .setCapturePreset(MediaRecorder.AudioSource.CAMCORDER);
761         if (AudioAttributes.isSystemUsage(usage)) {
762             builder.setSystemUsage(usage);
763         } else {
764             builder.setUsage(usage);
765         }
766         for (String tag : TEST_TAGS) {
767             builder.addTag(tag);
768         }
769         return builder.build();
770     }
771 
createTestFadeConfiguration()772     static AudioFadeConfiguration createTestFadeConfiguration() {
773         AudioFadeConfiguration configuration = new AudioFadeConfiguration();
774         configuration.fadeInDurationMs = TEST_FADE_IN_DURATION_MS;
775         configuration.fadeOutDurationMs = TEST_FADE_OUT_DURATION_MS;
776         configuration.fadeInDelayedForOffendersMs = TEST_FADE_IN_DELAYED_FOR_OFFENDERS_MS;
777         configuration.fadeState = FadeState.FADE_STATE_ENABLED_DEFAULT;
778         configuration.fadeableUsages = new int[]{MEDIA, GAME, UNKNOWN};
779         configuration.unfadeableContentTypes = new int[]{AudioContentType.SPEECH};
780         var emergencyAttribute = new android.media.audio.common.AudioAttributes();
781         emergencyAttribute.usage = EMERGENCY;
782         var navAttribute = new android.media.audio.common.AudioAttributes();
783         navAttribute.usage = AudioUsage.ASSISTANCE_NAVIGATION_GUIDANCE;
784         navAttribute.tags = TEST_TAGS;
785         configuration.unfadableAudioAttributes = List.of(emergencyAttribute, navAttribute);
786         configuration.fadeOutConfigurations = createFadeOutConfiguration();
787         configuration.fadeInConfigurations = createFadeInConfiguration();
788         configuration.name = TEST_FADE_CONFIGURATION_NAME;
789         return configuration;
790     }
791 
getTestDisabledCarFadeConfiguration()792     static CarAudioFadeConfiguration getTestDisabledCarFadeConfiguration() {
793         return new CarAudioFadeConfiguration.Builder(
794                 new FadeManagerConfiguration.Builder().setFadeState(
795                         FadeManagerConfiguration.FADE_STATE_DISABLED).build()).build();
796     }
797 
getTestCarFadeConfiguration()798     static CarAudioFadeConfiguration getTestCarFadeConfiguration() {
799         FadeManagerConfiguration.Builder fadeManagerBuilder =
800                 new FadeManagerConfiguration.Builder(TEST_FADE_OUT_DURATION_MS,
801                         TEST_FADE_IN_DURATION_MS);
802         fadeManagerBuilder.setFadeInDelayForOffenders(TEST_FADE_IN_DELAYED_FOR_OFFENDERS_MS);
803         fadeManagerBuilder.setFadeState(FadeManagerConfiguration.FADE_STATE_ENABLED_DEFAULT);
804         fadeManagerBuilder.setFadeableUsages(List.of(USAGE_MEDIA, USAGE_GAME, USAGE_UNKNOWN));
805         fadeManagerBuilder.setUnfadeableContentTypes(List.of(CONTENT_TYPE_SPEECH));
806         AudioAttributes.Builder emergencyBuilder = new AudioAttributes.Builder()
807                 .setSystemUsage(USAGE_EMERGENCY);
808         AudioAttributes.Builder navBuilder = new AudioAttributes.Builder()
809                 .setUsage(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
810         for (var tag : TEST_TAGS) {
811             AudioManagerHelper.addTagToAudioAttributes(navBuilder, tag);
812         }
813         fadeManagerBuilder.setUnfadeableAudioAttributes(List.of(emergencyBuilder.build(),
814                 navBuilder.build()));
815         fadeManagerBuilder.setFadeInDurationForUsage(USAGE_CALL_ASSISTANT,
816                 TEST_FADE_IN_CONFIG_DURATION_MS);
817         fadeManagerBuilder.setFadeInDurationForAudioAttributes(
818                 createMediaAudioAttributes(USAGE_SAFETY), TEST_FADE_IN_CONFIG_DURATION_MS);
819         fadeManagerBuilder.setFadeOutDurationForUsage(USAGE_ASSISTANT,
820                 TEST_FADE_OUT_CONFIG_DURATION_MS);
821         fadeManagerBuilder.setFadeOutDurationForAudioAttributes(
822                 createMediaAudioAttributes(USAGE_VEHICLE_STATUS), TEST_FADE_OUT_CONFIG_DURATION_MS);
823         return new CarAudioFadeConfiguration.Builder(fadeManagerBuilder.build())
824                 .setName(TEST_FADE_CONFIGURATION_NAME).build();
825     }
826 
createFadeInConfiguration()827     private static List<FadeConfiguration> createFadeInConfiguration() {
828         return createFadeConfiguration(TEST_FADE_IN_CONFIG_DURATION_MS,
829                 List.of(AudioUsage.CALL_ASSISTANT),
830                 List.of(createHALAudioAttribute(AudioUsage.SAFETY)));
831     }
832 
createFadeOutConfiguration()833     private static List<FadeConfiguration> createFadeOutConfiguration() {
834         return createFadeConfiguration(TEST_FADE_OUT_CONFIG_DURATION_MS,
835                 List.of(AudioUsage.ASSISTANT),
836                 List.of(createHALAudioAttribute(VEHICLE_STATUS)));
837     }
838 
createFadeConfiguration(long durationMs, List<Integer> usages, List<android.media.audio.common.AudioAttributes> audioAttribute)839     private static List<FadeConfiguration> createFadeConfiguration(long durationMs,
840             List<Integer> usages, List<android.media.audio.common.AudioAttributes> audioAttribute) {
841         var configs = new ArrayList<FadeConfiguration>(usages.size() + audioAttribute.size());
842         for (int c = 0; c < usages.size(); c++) {
843             var config = new FadeConfiguration();
844             config.fadeDurationMillis = durationMs;
845             var attributeOrUsage = new FadeConfiguration.AudioAttributesOrUsage();
846             attributeOrUsage.setUsage(usages.get(c));
847             config.audioAttributesOrUsage = attributeOrUsage;
848             configs.add(config);
849         }
850         for (int c = 0; c < audioAttribute.size(); c++) {
851             var config = new FadeConfiguration();
852             config.fadeDurationMillis = durationMs;
853             var attributeOrUsage = new FadeConfiguration.AudioAttributesOrUsage();
854             attributeOrUsage.setFadeAttribute(audioAttribute.get(c));
855             config.audioAttributesOrUsage = attributeOrUsage;
856             configs.add(config);
857         }
858         return configs;
859     }
860 }
861