• 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.car.oem.CarAudioFeaturesInfo.AUDIO_FEATURE_NO_FEATURE;
20 import static android.media.AudioAttributes.USAGE_ALARM;
21 import static android.media.AudioAttributes.USAGE_ANNOUNCEMENT;
22 import static android.media.AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY;
23 import static android.media.AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE;
24 import static android.media.AudioAttributes.USAGE_ASSISTANCE_SONIFICATION;
25 import static android.media.AudioAttributes.USAGE_EMERGENCY;
26 import static android.media.AudioAttributes.USAGE_MEDIA;
27 import static android.media.AudioAttributes.USAGE_NOTIFICATION;
28 import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
29 import static android.media.AudioAttributes.USAGE_SAFETY;
30 import static android.media.AudioAttributes.USAGE_VEHICLE_STATUS;
31 import static android.media.AudioAttributes.USAGE_VIRTUAL_SOURCE;
32 import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION;
33 import static android.media.AudioManager.AUDIOFOCUS_GAIN;
34 import static android.media.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
35 import static android.media.AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
36 
37 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.BOILERPLATE_CODE;
38 
39 import static org.mockito.ArgumentMatchers.anyInt;
40 import static org.mockito.ArgumentMatchers.eq;
41 import static org.mockito.Mockito.never;
42 import static org.mockito.Mockito.verify;
43 import static org.mockito.Mockito.when;
44 
45 import android.car.media.CarAudioManager;
46 import android.car.oem.AudioFocusEntry;
47 import android.car.oem.CarAudioFeaturesInfo;
48 import android.car.oem.OemCarAudioFocusResult;
49 import android.content.ContentResolver;
50 import android.content.pm.PackageManager;
51 import android.media.AudioFocusInfo;
52 import android.media.audiopolicy.AudioPolicy;
53 import android.util.SparseArray;
54 
55 import com.android.car.CarLocalServices;
56 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
57 import com.android.car.oem.CarOemAudioFocusProxyService;
58 import com.android.car.oem.CarOemProxyService;
59 
60 import org.mockito.Mock;
61 
62 import java.util.List;
63 
64 abstract class CarZonesAudioFocusTestBase {
65     protected static final String INVALID_CLIENT_ID = "invalid-client-id";
66     protected static final String INVALID_CLIENT_ID_2 = "invalid-client2-id";
67     protected static final String MEDIA_CLIENT_ID = "media-client-id";
68     protected static final String MEDIA_CLIENT_ID_2 = "media-client2-id";
69     protected static final String NAVIGATION_CLIENT_ID = "nav-client-id";
70     protected static final String NAVIGATION_CLIENT_ID_2 = "nav-client2-id";
71     protected static final String VOICE_COMMAND_CLIENT_ID = "voice-cmd-client-id";
72     protected static final String VOICE_COMMAND_CLIENT_ID_2 = "voice-cmd-client2-id";
73     protected static final String CALL_RING_CLIENT_ID = "call-ring-client-id";
74     protected static final String CALL_RING_CLIENT_ID_2 = "call-ring-client2-id";
75     protected static final String CALL_CLIENT_ID = "call-client-id";
76     protected static final String CALL_CLIENT_ID_2 = "call-client2-id";
77     protected static final String ALARM_CLIENT_ID = "alarm-client-id";
78     protected static final String ALARM_CLIENT_ID_2 = "alarm-client2-id";
79     protected static final String NOTIFICATION_CLIENT_ID = "notification-client-id";
80     protected static final String NOTIFICATION_CLIENT_ID_2 = "notification-client2-id";
81     protected static final String SYSTEM_SOUND_CLIENT_ID = "sys-sound-client-id";
82     protected static final String SYSTEM_SOUND_CLIENT_ID_2 = "sys-sound-client2-id";
83     protected static final String EMERGENCY_CLIENT_ID = "emergency-client-id";
84     protected static final String EMERGENCY_CLIENT_ID_2 = "emergency-client2-id";
85     protected static final String SAFETY_CLIENT_ID = "safety-client-id";
86     protected static final String SAFETY_CLIENT_ID_2 = "safety-client2-id";
87     protected static final String VEHICLE_STATUS_CLIENT_ID = "vehicle-status-client-id";
88     protected static final String VEHICLE_STATUS_CLIENT_ID_2 = "vehicle-status-client2-id";
89     protected static final String ANNOUNCEMENT_CLIENT_ID = "announcement-client-id";
90     protected static final String ANNOUNCEMENT_CLIENT_ID_2 = "announcement-client2-id";
91 
92     protected static final int PRIMARY_ZONE_ID = CarAudioManager.PRIMARY_AUDIO_ZONE;
93     protected static final int SECONDARY_ZONE_ID = CarAudioManager.PRIMARY_AUDIO_ZONE + 1;
94     protected static final int TEST_USER_ID = 10;
95     protected static final int INVALID_CLIENT_UID_1 = 1000005;
96     protected static final int INVALID_CLIENT_UID_2 = 1000007;
97     protected static final int MEDIA_CLIENT_UID_1 = 1086753;
98     protected static final int MEDIA_CLIENT_UID_2 = 1000009;
99     protected static final int NAVIGATION_CLIENT_UID_1 = 1010101;
100     protected static final int NAVIGATION_CLIENT_UID_2 = 1000207;
101     protected static final int VOICE_COMMAND_CLIENT_UID_1 = 1000305;
102     protected static final int VOICE_COMMAND_CLIENT_UID_2 = 1000307;
103     protected static final int CALL_RING_CLIENT_UID_1 = 1000405;
104     protected static final int CALL_RING_CLIENT_UID_2 = 1000407;
105     protected static final int CALL_CLIENT_UID_1 = 1086753;
106     protected static final int CALL_CLIENT_UID_2 = 1000507;
107     protected static final int ALARM_CLIENT_UID_1 = 1000605;
108     protected static final int ALARM_CLIENT_UID_2 = 1000607;
109     protected static final int NOTIFICATION_CLIENT_UID_1 = 1000705;
110     protected static final int NOTIFICATION_CLIENT_UID_2 = 1000707;
111     protected static final int SYSTEM_SOUND_CLIENT_UID_1 = 1000805;
112     protected static final int SYSTEM_SOUND_CLIENT_UID_2 = 1000807;
113     protected static final int EMERGENCY_CLIENT_UID_1 = 1000905;
114     protected static final int EMERGENCY_CLIENT_UID_2 = 1000907;
115     protected static final int SAFETY_CLIENT_UID_1 = 1001005;
116     protected static final int SAFETY_CLIENT_UID_2 = 1001007;
117     protected static final int VEHICLE_STATUS_CLIENT_UID_1 = 1001105;
118     protected static final int VEHICLE_STATUS_CLIENT_UID_2 = 1001107;
119     protected static final int ANNOUNCEMENT_CLIENT_UID_1 = 1001205;
120     protected static final int ANNOUNCEMENT_CLIENT_UID_2 = 1001207;
121 
122     protected static final AudioClientInfo INVALID_SOUND_INFO_1 = new AudioClientInfo(
123             USAGE_VIRTUAL_SOURCE, INVALID_CLIENT_UID_1, INVALID_CLIENT_ID);
124     protected static final AudioClientInfo INVALID_SOUND_INFO_2 = new AudioClientInfo(
125             USAGE_VIRTUAL_SOURCE, INVALID_CLIENT_UID_2, INVALID_CLIENT_ID_2);
126     protected static final AudioClientInfo MEDIA_INFO_1 = new AudioClientInfo(
127             USAGE_MEDIA, MEDIA_CLIENT_UID_1, MEDIA_CLIENT_ID);
128     protected static final AudioClientInfo MEDIA_INFO_2 = new AudioClientInfo(
129             USAGE_MEDIA, MEDIA_CLIENT_UID_2, MEDIA_CLIENT_ID_2);
130     protected static final AudioClientInfo NAVIGATION_INFO_1 = new AudioClientInfo(
131             USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, NAVIGATION_CLIENT_UID_1, NAVIGATION_CLIENT_ID);
132     protected static final AudioClientInfo NAVIGATION_INFO_2 = new AudioClientInfo(
133             USAGE_ASSISTANCE_NAVIGATION_GUIDANCE, NAVIGATION_CLIENT_UID_2, NAVIGATION_CLIENT_ID_2);
134     protected static final AudioClientInfo VOICE_COMMAND_INFO_1 = new AudioClientInfo(
135             USAGE_ASSISTANCE_ACCESSIBILITY, VOICE_COMMAND_CLIENT_UID_1, VOICE_COMMAND_CLIENT_ID);
136     protected static final AudioClientInfo VOICE_COMMAND_INFO_2 = new AudioClientInfo(
137             USAGE_ASSISTANCE_ACCESSIBILITY, VOICE_COMMAND_CLIENT_UID_2, VOICE_COMMAND_CLIENT_ID_2);
138     protected static final AudioClientInfo CALL_RING_INFO_1 = new AudioClientInfo(
139             USAGE_NOTIFICATION_RINGTONE, CALL_RING_CLIENT_UID_1, CALL_RING_CLIENT_ID);
140     protected static final AudioClientInfo CALL_RING_INFO_2 = new AudioClientInfo(
141             USAGE_NOTIFICATION_RINGTONE, CALL_RING_CLIENT_UID_2, CALL_RING_CLIENT_ID_2);
142     protected static final AudioClientInfo CALL_INFO_1 = new AudioClientInfo(
143             USAGE_VOICE_COMMUNICATION, CALL_CLIENT_UID_1, CALL_CLIENT_ID);
144     protected static final AudioClientInfo CALL_INFO_2 = new AudioClientInfo(
145             USAGE_VOICE_COMMUNICATION, CALL_CLIENT_UID_2, CALL_CLIENT_ID_2);
146     protected static final AudioClientInfo ALARM_INFO_1 = new AudioClientInfo(
147             USAGE_ALARM, ALARM_CLIENT_UID_1, ALARM_CLIENT_ID);
148     protected static final AudioClientInfo ALARM_INFO_2 = new AudioClientInfo(
149             USAGE_ALARM, ALARM_CLIENT_UID_2, ALARM_CLIENT_ID_2);
150     protected static final AudioClientInfo NOTIFICATION_INFO_1 = new AudioClientInfo(
151             USAGE_NOTIFICATION, NOTIFICATION_CLIENT_UID_1, NOTIFICATION_CLIENT_ID);
152     protected static final AudioClientInfo NOTIFICATION_INFO_2 = new AudioClientInfo(
153             USAGE_NOTIFICATION, NOTIFICATION_CLIENT_UID_2, NOTIFICATION_CLIENT_ID_2);
154     protected static final AudioClientInfo SYSTEM_SOUND_INFO_1 = new AudioClientInfo(
155             USAGE_ASSISTANCE_SONIFICATION, SYSTEM_SOUND_CLIENT_UID_1, SYSTEM_SOUND_CLIENT_ID);
156     protected static final AudioClientInfo SYSTEM_SOUND_INFO_2 = new AudioClientInfo(
157             USAGE_ASSISTANCE_SONIFICATION, SYSTEM_SOUND_CLIENT_UID_2, SYSTEM_SOUND_CLIENT_ID_2);
158     protected static final AudioClientInfo EMERGENCY_INFO_1 = new AudioClientInfo(
159             USAGE_EMERGENCY, EMERGENCY_CLIENT_UID_1, EMERGENCY_CLIENT_ID);
160     protected static final AudioClientInfo EMERGENCY_INFO_2 = new AudioClientInfo(
161             USAGE_EMERGENCY, EMERGENCY_CLIENT_UID_2, EMERGENCY_CLIENT_ID_2);
162     protected static final AudioClientInfo SAFETY_INFO_1 = new AudioClientInfo(
163             USAGE_SAFETY, SAFETY_CLIENT_UID_1, SAFETY_CLIENT_ID);
164     protected static final AudioClientInfo SAFETY_INFO_2 = new AudioClientInfo(
165             USAGE_SAFETY, SAFETY_CLIENT_UID_2, SAFETY_CLIENT_ID_2);
166     protected static final AudioClientInfo VEHICLE_STATUS_INFO_1 = new AudioClientInfo(
167             USAGE_VEHICLE_STATUS, VEHICLE_STATUS_CLIENT_UID_1, VEHICLE_STATUS_CLIENT_ID);
168     protected static final AudioClientInfo VEHICLE_STATUS_INFO_2 = new AudioClientInfo(
169             USAGE_VEHICLE_STATUS, VEHICLE_STATUS_CLIENT_UID_2, VEHICLE_STATUS_CLIENT_ID_2);
170     protected static final AudioClientInfo ANNOUNCEMENT_INFO_1 = new AudioClientInfo(
171             USAGE_ANNOUNCEMENT, ANNOUNCEMENT_CLIENT_UID_1, ANNOUNCEMENT_CLIENT_ID);
172     protected static final AudioClientInfo ANNOUNCEMENT_INFO_2 = new AudioClientInfo(
173             USAGE_ANNOUNCEMENT, ANNOUNCEMENT_CLIENT_UID_2, ANNOUNCEMENT_CLIENT_ID_2);
174 
175     @Mock
176     protected AudioManagerWrapper mMockAudioManager;
177     @Mock
178     protected AudioPolicy mAudioPolicy;
179     @Mock
180     protected CarAudioService mCarAudioService;
181     @Mock
182     protected CarZonesAudioFocus.CarFocusCallback mMockCarFocusCallback;
183     @Mock
184     protected CarOemProxyService mMockCarOemProxyService;
185     @Mock
186     protected CarOemAudioFocusProxyService mMockCarOemAudioFocusProxyService;
187     @Mock
188     private ContentResolver mContentResolver;
189     @Mock
190     private CarAudioSettings mCarAudioSettings;
191     @Mock
192     private PackageManager mMockPackageManager;
193     @Mock
194     private CarVolumeInfoWrapper mMockCarVolumeInfoWrapper;
195 
196     protected SparseArray<CarAudioZone> mCarAudioZones;
197 
setUp()198     public void setUp() {
199         mCarAudioZones = generateAudioZones();
200         CarLocalServices.removeServiceForTest(CarOemProxyService.class);
201         CarLocalServices.addService(CarOemProxyService.class, mMockCarOemProxyService);
202         when(mMockCarOemProxyService.isOemServiceReady()).thenReturn(false);
203         when(mMockCarOemProxyService.isOemServiceEnabled()).thenReturn(false);
204     }
205 
tearDown()206     public void tearDown() {
207         CarLocalServices.removeServiceForTest(CarOemProxyService.class);
208     }
209 
generateCallRequestForPrimaryZone()210     protected AudioFocusInfo generateCallRequestForPrimaryZone() {
211         return new AudioFocusInfoBuilder().setUsage(USAGE_VOICE_COMMUNICATION)
212                 .setGainRequest(AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK)
213                 .setClientId(CALL_CLIENT_ID)
214                 .setClientUid(CALL_CLIENT_UID_1).createAudioFocusInfo();
215     }
216 
generateMediaRequestForPrimaryZone(boolean isDelayedFocusEnabled)217     protected AudioFocusInfo generateMediaRequestForPrimaryZone(boolean isDelayedFocusEnabled) {
218         return new AudioFocusInfoBuilder().setUsage(USAGE_MEDIA)
219                 .setGainRequest(AUDIOFOCUS_GAIN)
220                 .setClientId(MEDIA_CLIENT_ID)
221                 .setDelayedFocusRequestEnable(isDelayedFocusEnabled)
222                 .setClientUid(MEDIA_CLIENT_UID_1).createAudioFocusInfo();
223     }
224 
requestFocusAndAssertIfRequestNotGranted(CarZonesAudioFocus carZonesAudioFocus, AudioFocusInfo audioFocusClient)225     protected void requestFocusAndAssertIfRequestNotGranted(CarZonesAudioFocus carZonesAudioFocus,
226             AudioFocusInfo audioFocusClient) {
227         requestFocusAndAssertIfRequestDiffers(carZonesAudioFocus, audioFocusClient,
228                 AUDIOFOCUS_REQUEST_GRANTED);
229     }
230 
requestFocusAndAssertIfRequestDiffers(CarZonesAudioFocus carZonesAudioFocus, AudioFocusInfo audioFocusClient, int expectedAudioFocusResults)231     private void requestFocusAndAssertIfRequestDiffers(CarZonesAudioFocus carZonesAudioFocus,
232             AudioFocusInfo audioFocusClient, int expectedAudioFocusResults) {
233         carZonesAudioFocus.onAudioFocusRequest(audioFocusClient, expectedAudioFocusResults);
234         verify(mMockAudioManager)
235                 .setFocusRequestResult(audioFocusClient, expectedAudioFocusResults, mAudioPolicy);
236     }
237 
abandonFocusAndAssertIfAbandonNotGranted(CarZonesAudioFocus carZonesAudioFocus, AudioFocusInfo audioFocusClient)238     protected void abandonFocusAndAssertIfAbandonNotGranted(CarZonesAudioFocus carZonesAudioFocus,
239             AudioFocusInfo audioFocusClient) {
240         carZonesAudioFocus.onAudioFocusAbandon(audioFocusClient);
241         verify(mMockAudioManager, never()).dispatchAudioFocusChange(eq(audioFocusClient),
242                 anyInt(), eq(mAudioPolicy));
243     }
244 
generateAudioZones()245     protected SparseArray<CarAudioZone> generateAudioZones() {
246         int testZoneConfigId = 0;
247         SparseArray<CarAudioZone> zones = new SparseArray<>(2);
248         CarAudioContext testCarAudioContext =
249                 new CarAudioContext(CarAudioContext.getAllContextsInfo(),
250                         /* useCoreAudioRouting= */ false);
251         CarAudioZone primaryZone = new CarAudioZone(testCarAudioContext, "Primary zone",
252                 PRIMARY_ZONE_ID);
253         CarAudioZone secondaryZone = new CarAudioZone(testCarAudioContext, "Secondary zone",
254                 SECONDARY_ZONE_ID);
255         CarAudioZoneConfig primaryZoneConfig =
256                 new CarAudioZoneConfig.Builder("Primary zone config", PRIMARY_ZONE_ID,
257                         testZoneConfigId, /* isDefault= */ true).build();
258         CarAudioZoneConfig secondaryZoneConfig =
259                 new CarAudioZoneConfig.Builder("Secondary zone config", SECONDARY_ZONE_ID,
260                         testZoneConfigId, /* isDefault= */ true).build();
261         primaryZone.addZoneConfig(primaryZoneConfig);
262         secondaryZone.addZoneConfig(secondaryZoneConfig);
263         zones.put(PRIMARY_ZONE_ID, primaryZone);
264         zones.put(SECONDARY_ZONE_ID, secondaryZone);
265         return zones;
266     }
267 
getCarZonesAudioFocus(CarZonesAudioFocus.CarFocusCallback carFocusCallback)268     protected CarZonesAudioFocus getCarZonesAudioFocus(CarZonesAudioFocus.CarFocusCallback
269             carFocusCallback) {
270         CarZonesAudioFocus carZonesAudioFocus =
271                 CarZonesAudioFocus.createCarZonesAudioFocus(mMockAudioManager,
272                         mMockPackageManager, mCarAudioZones, mCarAudioSettings, carFocusCallback,
273                         mMockCarVolumeInfoWrapper, new CarAudioFeaturesInfo.Builder(
274                                 AUDIO_FEATURE_NO_FEATURE).build());
275         carZonesAudioFocus.setOwningPolicy(mCarAudioService, mAudioPolicy);
276 
277         return carZonesAudioFocus;
278     }
279 
getCarZonesAudioFocus()280     protected CarZonesAudioFocus getCarZonesAudioFocus() {
281         return getCarZonesAudioFocus(mMockCarFocusCallback);
282     }
283 
setUpRejectNavigationOnCallValue(boolean rejectNavigationOnCall)284     protected void setUpRejectNavigationOnCallValue(boolean rejectNavigationOnCall) {
285         when(mCarAudioSettings.getContentResolverForUser(TEST_USER_ID))
286                 .thenReturn(mContentResolver);
287         when(mCarAudioSettings.isRejectNavigationOnCallEnabledInSettings(TEST_USER_ID))
288                 .thenReturn(rejectNavigationOnCall);
289     }
290 
getAudioFocusResults(AudioFocusEntry entry, List<AudioFocusEntry> lostEntries, List<AudioFocusEntry> blockedEntries, int results)291     protected OemCarAudioFocusResult getAudioFocusResults(AudioFocusEntry entry,
292             List<AudioFocusEntry> lostEntries, List<AudioFocusEntry> blockedEntries, int results) {
293         return new OemCarAudioFocusResult.Builder(lostEntries, blockedEntries, results)
294                 .setAudioFocusEntry(entry).build();
295     }
296 
297     @ExcludeFromCodeCoverageGeneratedReport(reason = BOILERPLATE_CODE)
298     public static final class AudioClientInfo {
299         private final int mUsage;
300         private final int mClientUid;
301         private final String mClientId;
302 
AudioClientInfo(int usage, int clientUid, String clientId)303         AudioClientInfo(int usage, int clientUid, String clientId) {
304             mUsage = usage;
305             mClientUid = clientUid;
306             mClientId = clientId;
307         }
308 
getUsage()309         public int getUsage() {
310             return mUsage;
311         }
312 
getClientUid()313         public int getClientUid() {
314             return mClientUid;
315         }
316 
getClientId()317         public String getClientId() {
318             return mClientId;
319         }
320     }
321 }
322