xref: /aosp_15_r20/frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2015 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 #define LOG_TAG "APM::AudioPolicyEngine"
18 //#define LOG_NDEBUG 0
19 
20 //#define VERY_VERBOSE_LOGGING
21 #ifdef VERY_VERBOSE_LOGGING
22 #define ALOGVV ALOGV
23 #else
24 #define ALOGVV(a...) do { } while(0)
25 #endif
26 
27 #include "Engine.h"
28 #include <android-base/macros.h>
29 #include <AudioPolicyManagerObserver.h>
30 #include <PolicyAudioPort.h>
31 #include <IOProfile.h>
32 #include <AudioIODescriptorInterface.h>
33 #include <com_android_media_audioserver.h>
34 #include <policy.h>
35 #include <media/AudioContainers.h>
36 #include <utils/String8.h>
37 #include <utils/Log.h>
38 
39 namespace android::audio_policy {
40 
getLegacyStrategy()41 static const std::vector<legacy_strategy_map>& getLegacyStrategy() {
42     static const std::vector<legacy_strategy_map> legacyStrategy = getLegacyStrategyMap();
43     return legacyStrategy;
44 }
45 
loadFromHalConfigWithFallback(const media::audio::common::AudioHalEngineConfig & aidlConfig)46 status_t Engine::loadFromHalConfigWithFallback(
47         const media::audio::common::AudioHalEngineConfig& aidlConfig) {
48     return loadWithFallback(aidlConfig);
49 }
50 
loadFromXmlConfigWithFallback(const std::string & xmlFilePath)51 status_t Engine::loadFromXmlConfigWithFallback(const std::string& xmlFilePath) {
52     return loadWithFallback(xmlFilePath);
53 }
54 
55 template<typename T>
loadWithFallback(const T & configSource)56 status_t Engine::loadWithFallback(const T& configSource) {
57     auto result = EngineBase::loadAudioPolicyEngineConfig(configSource, false /*isConfigurable*/);
58     ALOGE_IF(result.nbSkippedElement != 0,
59              "Policy Engine configuration is partially invalid, skipped %zu elements",
60              result.nbSkippedElement);
61 
62     auto legacyStrategy = getLegacyStrategy();
63     for (const auto &strategy : legacyStrategy) {
64         mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
65     }
66 
67     return OK;
68 }
69 
70 
setForceUse(audio_policy_force_use_t usage,audio_policy_forced_cfg_t config)71 status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
72 {
73     switch(usage) {
74     case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
75         if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
76             config != AUDIO_POLICY_FORCE_NONE) {
77             ALOGW("setForceUse() invalid config %d for COMMUNICATION", config);
78             return BAD_VALUE;
79         }
80         break;
81     case AUDIO_POLICY_FORCE_FOR_MEDIA:
82         if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
83             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
84             config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
85             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
86             config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
87             ALOGW("setForceUse() invalid config %d for MEDIA", config);
88             return BAD_VALUE;
89         }
90         break;
91     case AUDIO_POLICY_FORCE_FOR_RECORD:
92         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
93             config != AUDIO_POLICY_FORCE_NONE) {
94             ALOGW("setForceUse() invalid config %d for RECORD", config);
95             return BAD_VALUE;
96         }
97         break;
98     case AUDIO_POLICY_FORCE_FOR_DOCK:
99         if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
100             config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
101             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
102             config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
103             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
104             ALOGW("setForceUse() invalid config %d for DOCK", config);
105             return BAD_VALUE;
106         }
107         break;
108     case AUDIO_POLICY_FORCE_FOR_SYSTEM:
109         if (config != AUDIO_POLICY_FORCE_NONE &&
110             config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
111             ALOGW("setForceUse() invalid config %d for SYSTEM", config);
112             return BAD_VALUE;
113         }
114         break;
115     case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
116         if (config != AUDIO_POLICY_FORCE_NONE &&
117             config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
118             ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
119             return BAD_VALUE;
120         }
121         break;
122     case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
123         if (config != AUDIO_POLICY_FORCE_NONE &&
124                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
125                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
126                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
127             ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
128             return BAD_VALUE;
129         }
130         break;
131     case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
132         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_BT_BLE
133                 && config != AUDIO_POLICY_FORCE_NONE) {
134             ALOGW("setForceUse() invalid config %d for VIBRATE_RINGING", config);
135             return BAD_VALUE;
136         }
137         break;
138     default:
139         ALOGW("setForceUse() invalid usage %d", usage);
140         return BAD_VALUE;
141     }
142     return EngineBase::setForceUse(usage, config);
143 }
144 
isBtScoActive(DeviceVector & availableOutputDevices) const145 bool Engine::isBtScoActive(DeviceVector& availableOutputDevices) const {
146     // SCO is considered active if:
147     // 1) a SCO device is connected
148     // 2) the preferred device for PHONE strategy is BT SCO: this is controlled only by java
149     // AudioService and is only true if the SCO audio link as been confirmed active by BT.
150     if (availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()) {
151         return false;
152     }
153 
154     if (!audio_is_bluetooth_out_sco_device(
155             getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE))) {
156         return false;
157     }
158 
159     return true;
160 }
161 
filterOutputDevicesForStrategy(legacy_strategy strategy,DeviceVector & availableOutputDevices,const SwAudioOutputCollection & outputs) const162 void Engine::filterOutputDevicesForStrategy(legacy_strategy strategy,
163                                             DeviceVector& availableOutputDevices,
164                                             const SwAudioOutputCollection &outputs) const
165 {
166     DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
167 
168     if (com::android::media::audioserver::use_bt_sco_for_media()) {
169         // remove A2DP and LE Audio devices whenever BT SCO is in use
170         if (isBtScoActive(availableOutputDevices)) {
171             availableOutputDevices.remove(
172                 availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllA2dpSet()));
173             availableOutputDevices.remove(
174                 availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllBleSet()));
175         }
176     }
177 
178     switch (strategy) {
179     case STRATEGY_SONIFICATION_RESPECTFUL: {
180         if (!(isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL)))) {
181             // routing is same as media without the "remote" device
182             availableOutputDevices.remove(availableOutputDevices.getDevicesFromType(
183                     AUDIO_DEVICE_OUT_REMOTE_SUBMIX));
184         }
185         } break;
186     case STRATEGY_DTMF:
187     case STRATEGY_PHONE: {
188         // Force use of only devices on primary output if:
189         // - in call AND
190         //   - cannot route from voice call RX OR
191         //   - audio HAL version is < 3.0 and TX device is on the primary HW module
192         if (getPhoneState() == AUDIO_MODE_IN_CALL) {
193             sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
194             if (primaryOutput != nullptr) {
195                 audio_devices_t txDevice = AUDIO_DEVICE_NONE;
196                 sp<DeviceDescriptor> txDeviceDesc =
197                         getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
198                 if (txDeviceDesc != nullptr) {
199                     txDevice = txDeviceDesc->type();
200                 }
201                 DeviceVector availPrimaryInputDevices =
202                         availableInputDevices.getDevicesFromHwModule(
203                             primaryOutput->getModuleHandle());
204 
205                 // TODO: getPrimaryOutput return only devices from first module in
206                 // audio_policy_configuration.xml, hearing aid is not there, but it's
207                 // a primary device
208                 // FIXME: this is not the right way of solving this problem
209                 DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypes(
210                         primaryOutput->supportedDevices().types());
211                 availPrimaryOutputDevices.add(
212                         availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));
213 
214                 if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
215                                                      String8(""), AUDIO_FORMAT_DEFAULT) == nullptr)
216                     || ((availPrimaryInputDevices.getDevice(
217                             txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
218                      (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
219                     availableOutputDevices = availPrimaryOutputDevices;
220                 }
221             } else {
222                 ALOGE("%s, STRATEGY_PHONE: Primary output not found", __func__);
223             }
224         }
225         // Do not use A2DP devices when in call but use them when not in call
226         // (e.g for voice mail playback)
227         if (isInCall()) {
228             availableOutputDevices.remove(availableOutputDevices.getDevicesFromTypes({
229                     AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
230                     AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, }));
231         }
232         // If connected to a dock, never use the device speaker for calls
233         if (!availableOutputDevices.getDevicesFromTypes({AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET})
234                 .isEmpty()) {
235             availableOutputDevices.remove(
236                     availableOutputDevices.getDevicesFromTypes({AUDIO_DEVICE_OUT_SPEAKER}));
237         }
238         } break;
239     case STRATEGY_ACCESSIBILITY: {
240         // do not route accessibility prompts to a digital output currently configured with a
241         // compressed format as they would likely not be mixed and dropped.
242         for (size_t i = 0; i < outputs.size(); i++) {
243             sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
244             if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) {
245                 availableOutputDevices.remove(desc->devices().getDevicesFromTypes({
246                         AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_SPDIF,
247                         AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_EARC}));
248             }
249         }
250         } break;
251     default:
252         break;
253     }
254 }
255 
remapStrategyFromContext(product_strategy_t strategy,const SwAudioOutputCollection & outputs) const256 product_strategy_t Engine::remapStrategyFromContext(product_strategy_t strategy,
257                                                  const SwAudioOutputCollection &outputs) const {
258     auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
259                           mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
260 
261     if (isInCall()) {
262         switch (legacyStrategy) {
263         case STRATEGY_ACCESSIBILITY:
264         case STRATEGY_DTMF:
265         case STRATEGY_MEDIA:
266         case STRATEGY_SONIFICATION:
267         case STRATEGY_SONIFICATION_RESPECTFUL:
268             legacyStrategy = STRATEGY_PHONE;
269             break;
270 
271         default:
272             return strategy;
273         }
274     } else {
275         switch (legacyStrategy) {
276         case STRATEGY_SONIFICATION_RESPECTFUL:
277         case STRATEGY_SONIFICATION:
278             if (outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
279                 legacyStrategy = STRATEGY_PHONE;
280             }
281             break;
282 
283         case STRATEGY_ACCESSIBILITY:
284             if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
285                     outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) {
286                 legacyStrategy = STRATEGY_SONIFICATION;
287             }
288             break;
289 
290         default:
291             return strategy;
292         }
293     }
294     return getProductStrategyFromLegacy(legacyStrategy);
295 }
296 
getDevicesForStrategyInt(legacy_strategy strategy,DeviceVector availableOutputDevices,const SwAudioOutputCollection & outputs) const297 DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
298                                               DeviceVector availableOutputDevices,
299                                               const SwAudioOutputCollection &outputs) const
300 {
301     DeviceVector devices;
302 
303     switch (strategy) {
304 
305     case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
306         devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
307         break;
308 
309     case STRATEGY_PHONE: {
310         // TODO(b/243670205): remove this logic that gives preference to last removable devices
311         // once a UX decision has been made
312         devices = availableOutputDevices.getFirstDevicesFromTypes(
313                         getLastRemovableMediaDevices(GROUP_NONE, {
314                             // excluding HEARING_AID and BLE_HEADSET because Dialer uses
315                             // setCommunicationDevice to select them explicitly
316                             AUDIO_DEVICE_OUT_HEARING_AID,
317                             AUDIO_DEVICE_OUT_BLE_HEADSET,
318                             AUDIO_DEVICE_OUT_AUX_DIGITAL
319                             }));
320         if (!devices.isEmpty()) break;
321         devices = availableOutputDevices.getFirstDevicesFromTypes({
322                 AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_EARPIECE,
323                 AUDIO_DEVICE_OUT_SPEAKER});
324     } break;
325 
326     case STRATEGY_SONIFICATION:
327     case STRATEGY_ENFORCED_AUDIBLE:
328         // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
329         // except:
330         //   - when in call where it doesn't default to STRATEGY_PHONE behavior
331         //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
332 
333         if ((strategy == STRATEGY_SONIFICATION) ||
334                 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
335             // favor dock over speaker when available
336             devices = availableOutputDevices.getFirstDevicesFromTypes({
337                     AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_SPEAKER});
338         }
339 
340         // if SCO headset is connected and we are told to use it, play ringtone over
341         // speaker and BT SCO
342         if (!availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()
343                 && audio_is_bluetooth_out_sco_device(getPreferredDeviceTypeForLegacyStrategy(
344                             availableOutputDevices, STRATEGY_PHONE))) {
345             DeviceVector devices2 = availableOutputDevices.getFirstDevicesFromTypes({
346                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
347                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
348             // devices2 cannot be empty at this point
349             // Use ONLY Bluetooth SCO output when ringing in vibration mode
350             if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
351                         && (strategy == STRATEGY_ENFORCED_AUDIBLE))
352                     && (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
353                         == AUDIO_POLICY_FORCE_BT_SCO)) {
354                 devices = devices2;
355                 break;
356             }
357             // Use both Bluetooth SCO and phone default output when ringing in normal mode
358             if (strategy == STRATEGY_SONIFICATION) {
359                 devices.replaceDevicesByType(
360                         AUDIO_DEVICE_OUT_SPEAKER,
361                         availableOutputDevices.getDevicesFromType(
362                                 AUDIO_DEVICE_OUT_SPEAKER_SAFE));
363             }
364             devices.add(devices2);
365             break;
366         }
367 
368         // if LEA headset is connected and we are told to use it, play ringtone over
369         // speaker and BT LEA
370         if (!availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllBleSet()).isEmpty()
371                 && audio_is_ble_out_device(getPreferredDeviceTypeForLegacyStrategy(
372                                        availableOutputDevices, STRATEGY_PHONE))) {
373             DeviceVector devices2;
374             devices2 = availableOutputDevices.getFirstDevicesFromTypes({
375                     AUDIO_DEVICE_OUT_BLE_HEADSET, AUDIO_DEVICE_OUT_BLE_SPEAKER});
376             // devices2 cannot be empty at this point
377             // Use ONLY Bluetooth LEA output when ringing in vibration mode
378             if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
379                         && (strategy == STRATEGY_ENFORCED_AUDIBLE))
380                     && (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
381                                                == AUDIO_POLICY_FORCE_BT_BLE)) {
382                 devices = devices2;
383                 break;
384             }
385             // Use both Bluetooth LEA and phone default output when ringing in normal mode
386             if (strategy == STRATEGY_SONIFICATION) {
387                 devices.replaceDevicesByType(
388                         AUDIO_DEVICE_OUT_SPEAKER,
389                         availableOutputDevices.getDevicesFromType(
390                                 AUDIO_DEVICE_OUT_SPEAKER_SAFE));
391             }
392             devices.add(devices2);
393             break;
394         }
395 
396         // The second device used for sonification is the same as the device used by media strategy
397         FALLTHROUGH_INTENDED;
398 
399     case STRATEGY_DTMF:
400     case STRATEGY_ACCESSIBILITY:
401     case STRATEGY_SONIFICATION_RESPECTFUL:
402     case STRATEGY_REROUTING:
403     case STRATEGY_MEDIA: {
404         DeviceVector devices2;
405         if (strategy != STRATEGY_SONIFICATION) {
406             // no sonification on remote submix (e.g. WFD)
407             sp<DeviceDescriptor> remoteSubmix;
408             if ((remoteSubmix = availableOutputDevices.getDevice(
409                     AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
410                     AUDIO_FORMAT_DEFAULT)) != nullptr) {
411                 devices2.add(remoteSubmix);
412             }
413         }
414 
415         if ((devices2.isEmpty()) &&
416             (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
417             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
418         }
419 
420         // LE audio broadcast device is only used if:
421         // - No call is active
422         // - the highest priority active strategy is not PHONE or TRANSMITTED_THROUGH_SPEAKER
423         // OR the LE audio unicast device is not active
424         if (devices2.isEmpty() && !isInCall()
425                 // also skipping routing queries from PHONE and TRANSMITTED_THROUGH_SPEAKER here
426                 // so this code is not dependent on breaks for other strategies above
427                 && (strategy != STRATEGY_PHONE)
428                 && (strategy != STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
429             legacy_strategy topActiveStrategy = STRATEGY_NONE;
430             for (const auto &ps : getOrderedProductStrategies()) {
431                 if (outputs.isStrategyActive(ps)) {
432                     topActiveStrategy =  mLegacyStrategyMap.find(ps) != end(mLegacyStrategyMap) ?
433                             mLegacyStrategyMap.at(ps) : STRATEGY_NONE;
434                     break;
435                 }
436             }
437 
438             if ((topActiveStrategy != STRATEGY_PHONE
439                         && topActiveStrategy != STRATEGY_TRANSMITTED_THROUGH_SPEAKER)
440                     || !outputs.isAnyDeviceTypeActive(getAudioDeviceOutLeAudioUnicastSet())) {
441                 devices2 =
442                         availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_BLE_BROADCAST);
443             }
444         }
445 
446         if (devices2.isEmpty() && (getLastRemovableMediaDevices().size() > 0)) {
447             std::vector<audio_devices_t> excludedDevices;
448             // no sonification on aux digital (e.g. HDMI)
449             if (strategy == STRATEGY_SONIFICATION) {
450                 excludedDevices.push_back(AUDIO_DEVICE_OUT_AUX_DIGITAL);
451             }
452             if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
453                 // Get the last connected device of wired and bluetooth a2dp
454                 devices2 = availableOutputDevices.getFirstDevicesFromTypes(
455                         getLastRemovableMediaDevices(GROUP_NONE, excludedDevices));
456                 if (com::android::media::audioserver::use_bt_sco_for_media()) {
457                     if (isBtScoActive(availableOutputDevices)
458                          && !(devices2.getDevicesFromTypes(
459                                  getAudioDeviceOutAllA2dpSet()).isEmpty()
460                              && devices2.getDevicesFromTypes(
461                                      getAudioDeviceOutAllBleSet()).isEmpty())) {
462                         devices2 = availableOutputDevices.getFirstDevicesFromTypes(
463                                 { AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT,
464                                   AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
465                                   AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
466                     }
467                 }
468             } else {
469                 // Get the last connected device of wired except bluetooth a2dp
470                 devices2 = availableOutputDevices.getFirstDevicesFromTypes(
471                         getLastRemovableMediaDevices(GROUP_WIRED, excludedDevices));
472             }
473         }
474 
475         if ((devices2.isEmpty()) &&
476                 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
477             devices2 = availableOutputDevices.getDevicesFromType(
478                     AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
479         }
480 
481         if (devices2.isEmpty()) {
482             devices2 = availableOutputDevices.getFirstDevicesFromTypes({
483                         AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_SPEAKER});
484         }
485 
486         DeviceVector devices3;
487         if (strategy == STRATEGY_MEDIA) {
488             // ARC, SPDIF and AUX_LINE can co-exist with others.
489             devices3 = availableOutputDevices.getDevicesFromTypes({
490                     AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_HDMI_EARC,
491                     AUDIO_DEVICE_OUT_SPDIF, AUDIO_DEVICE_OUT_AUX_LINE,
492                     });
493         }
494 
495         devices2.add(devices3);
496         // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
497         // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
498         devices.add(devices2);
499 
500         // If hdmi system audio mode is on, remove speaker out of output list.
501         if ((strategy == STRATEGY_MEDIA) &&
502             (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
503                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
504             devices.remove(devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
505         }
506 
507         bool mediaActiveLocally =
508                 outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_MUSIC),
509                                         SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
510                 || outputs.isActiveLocally(
511                     toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
512                     SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
513 
514         bool ringActiveLocally = outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_RING), 0);
515         // - for STRATEGY_SONIFICATION and ringtone active:
516         // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
517         // - for STRATEGY_SONIFICATION_RESPECTFUL:
518         // if no media is playing on the device, check for mandatory use of "safe" speaker
519         // when media would have played on speaker, and the safe speaker path is available
520         if (strategy == STRATEGY_SONIFICATION || ringActiveLocally
521             || (strategy == STRATEGY_SONIFICATION_RESPECTFUL && !mediaActiveLocally)) {
522             devices.replaceDevicesByType(
523                     AUDIO_DEVICE_OUT_SPEAKER,
524                     availableOutputDevices.getDevicesFromType(
525                             AUDIO_DEVICE_OUT_SPEAKER_SAFE));
526         }
527         } break;
528 
529     case STRATEGY_CALL_ASSISTANT:
530         devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
531         break;
532 
533     case STRATEGY_NONE:
534         // Happens when internal strategies are processed ("rerouting", "patch"...)
535         break;
536 
537     default:
538         ALOGW("%s unknown strategy: %d", __func__, strategy);
539         break;
540     }
541 
542     if (devices.isEmpty()) {
543         ALOGI("%s no device found for strategy %d", __func__, strategy);
544         sp<DeviceDescriptor> defaultOutputDevice = getApmObserver()->getDefaultOutputDevice();
545         if (defaultOutputDevice != nullptr) {
546             devices.add(defaultOutputDevice);
547         }
548         ALOGE_IF(devices.isEmpty(),
549                  "%s no default device defined", __func__);
550     }
551 
552     ALOGVV("%s strategy %d, device %s", __func__,
553            strategy, dumpDeviceTypes(devices.types()).c_str());
554     return devices;
555 }
556 
getPreferredAvailableDevicesForInputSource(const DeviceVector & availableInputDevices,audio_source_t inputSource) const557 DeviceVector Engine::getPreferredAvailableDevicesForInputSource(
558             const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
559     DeviceVector preferredAvailableDevVec = {};
560     AudioDeviceTypeAddrVector preferredDevices;
561     const status_t status = getDevicesForRoleAndCapturePreset(
562             inputSource, DEVICE_ROLE_PREFERRED, preferredDevices);
563     if (status == NO_ERROR) {
564         // Only use preferred devices when they are all available.
565         preferredAvailableDevVec =
566                 availableInputDevices.getDevicesFromDeviceTypeAddrVec(preferredDevices);
567         if (preferredAvailableDevVec.size() == preferredDevices.size()) {
568             ALOGVV("%s using pref device %s for source %u",
569                    __func__, preferredAvailableDevVec.toString().c_str(), inputSource);
570             return preferredAvailableDevVec;
571         }
572     }
573     return preferredAvailableDevVec;
574 }
575 
getDisabledDevicesForInputSource(const DeviceVector & availableInputDevices,audio_source_t inputSource) const576 DeviceVector Engine::getDisabledDevicesForInputSource(
577             const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
578     DeviceVector disabledDevices = {};
579     AudioDeviceTypeAddrVector disabledDevicesTypeAddr;
580     const status_t status = getDevicesForRoleAndCapturePreset(
581             inputSource, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr);
582     if (status == NO_ERROR) {
583         disabledDevices =
584                 availableInputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr);
585     }
586     return disabledDevices;
587 }
588 
getDeviceForInputSource(audio_source_t inputSource) const589 sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const
590 {
591     const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
592     const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
593     const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
594     DeviceVector availableDevices = availableInputDevices;
595     sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
596     DeviceVector availablePrimaryDevices = primaryOutput == nullptr ? DeviceVector()
597             : availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
598     sp<DeviceDescriptor> device;
599 
600     // when a call is active, force device selection to match source VOICE_COMMUNICATION
601     // for most other input sources to avoid rerouting call TX audio
602     if (isInCall()) {
603         switch (inputSource) {
604         case AUDIO_SOURCE_DEFAULT:
605         case AUDIO_SOURCE_MIC:
606         case AUDIO_SOURCE_VOICE_RECOGNITION:
607         case AUDIO_SOURCE_UNPROCESSED:
608         case AUDIO_SOURCE_HOTWORD:
609         case AUDIO_SOURCE_CAMCORDER:
610         case AUDIO_SOURCE_VOICE_PERFORMANCE:
611         case AUDIO_SOURCE_ULTRASOUND:
612             inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
613             break;
614         default:
615             break;
616         }
617     }
618 
619     // Use the preferred device for the input source if it is available.
620     DeviceVector preferredInputDevices = getPreferredAvailableDevicesForInputSource(
621             availableDevices, inputSource);
622     if (!preferredInputDevices.isEmpty()) {
623         // Currently, only support single device for input. The public JAVA API also only
624         // support setting single device as preferred device. In that case, returning the
625         // first device is OK here.
626         return preferredInputDevices[0];
627     }
628     // Remove the disabled device for the input source from the available input device list.
629     DeviceVector disabledInputDevices = getDisabledDevicesForInputSource(
630             availableDevices, inputSource);
631     availableDevices.remove(disabledInputDevices);
632 
633     audio_devices_t commDeviceType =
634         getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE);
635 
636     switch (inputSource) {
637     case AUDIO_SOURCE_DEFAULT:
638     case AUDIO_SOURCE_MIC:
639         device = availableDevices.getDevice(
640                 AUDIO_DEVICE_IN_BLUETOOTH_A2DP, String8(""), AUDIO_FORMAT_DEFAULT);
641         if (device != nullptr) break;
642         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
643             device = availableDevices.getDevice(
644                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
645             if (device != nullptr) break;
646         }
647         device = availableDevices.getFirstExistingDevice({
648                 AUDIO_DEVICE_IN_WIRED_HEADSET,
649                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
650                 AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
651         break;
652 
653     case AUDIO_SOURCE_VOICE_COMMUNICATION:
654         // Allow only use of devices on primary input if in call and HAL does not support routing
655         // to voice call path.
656         if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
657                 (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX,
658                         String8(""), AUDIO_FORMAT_DEFAULT)) == nullptr) {
659             if (!availablePrimaryDevices.isEmpty()) {
660                 availableDevices = availablePrimaryDevices;
661             } else {
662                 ALOGE("%s, AUDIO_SOURCE_VOICE_COMMUNICATION: Primary devices not found", __func__);
663             }
664         }
665 
666         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
667             // if SCO device is requested but no SCO device is available, fall back to default case
668             device = availableDevices.getDevice(
669                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
670             if (device != nullptr) {
671                 break;
672             }
673         }
674         switch (commDeviceType) {
675         case AUDIO_DEVICE_OUT_SPEAKER:
676             device = availableDevices.getFirstExistingDevice({
677                     AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC,
678                     AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_USB_HEADSET});
679             break;
680         case AUDIO_DEVICE_OUT_BLE_HEADSET:
681             device = availableDevices.getDevice(
682                     AUDIO_DEVICE_IN_BLE_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
683             if (device != nullptr) {
684                 break;
685             }
686             ALOGE("%s LE Audio selected for communication but input device not available",
687                     __func__);
688             FALLTHROUGH_INTENDED;
689         default:    // FORCE_NONE
690             device = availableDevices.getFirstExistingDevice({
691                     AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
692                     AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
693                     AUDIO_DEVICE_IN_BUILTIN_MIC});
694             break;
695         }
696         break;
697 
698     case AUDIO_SOURCE_VOICE_RECOGNITION:
699     case AUDIO_SOURCE_UNPROCESSED:
700         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
701             device = availableDevices.getDevice(
702                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
703             if (device != nullptr) break;
704         }
705         // we need to make BLUETOOTH_BLE has higher priority than BUILTIN_MIC,
706         // because sometimes user want to do voice search by bt remote
707         // even if BUILDIN_MIC is available.
708         device = availableDevices.getFirstExistingDevice({
709                 AUDIO_DEVICE_IN_WIRED_HEADSET,
710                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
711                 AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_IN_BUILTIN_MIC});
712 
713         break;
714     case AUDIO_SOURCE_HOTWORD:
715         // We should not use primary output criteria for Hotword but rather limit
716         // to devices attached to the same HW module as the build in mic
717         if (!availablePrimaryDevices.isEmpty()) {
718             availableDevices = availablePrimaryDevices;
719         } else {
720             ALOGE("%s, AUDIO_SOURCE_HOTWORD: Primary devices not found", __func__);
721         }
722         if (audio_is_bluetooth_out_sco_device(commDeviceType)) {
723             device = availableDevices.getDevice(
724                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
725             if (device != nullptr) break;
726         }
727         device = availableDevices.getFirstExistingDevice({
728                 AUDIO_DEVICE_IN_WIRED_HEADSET,
729                 AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_IN_USB_DEVICE,
730                 AUDIO_DEVICE_IN_BUILTIN_MIC});
731         break;
732     case AUDIO_SOURCE_CAMCORDER:
733         // For a device without built-in mic, adding usb device
734         device = availableDevices.getFirstExistingDevice({
735                 AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC,
736                 AUDIO_DEVICE_IN_USB_DEVICE});
737         break;
738     case AUDIO_SOURCE_VOICE_DOWNLINK:
739     case AUDIO_SOURCE_VOICE_CALL:
740     case AUDIO_SOURCE_VOICE_UPLINK:
741         device = availableDevices.getDevice(
742                 AUDIO_DEVICE_IN_VOICE_CALL, String8(""), AUDIO_FORMAT_DEFAULT);
743         break;
744     case AUDIO_SOURCE_VOICE_PERFORMANCE:
745         device = availableDevices.getFirstExistingDevice({
746                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
747                 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BLUETOOTH_BLE,
748                 AUDIO_DEVICE_IN_BUILTIN_MIC});
749         break;
750     case AUDIO_SOURCE_REMOTE_SUBMIX:
751         device = availableDevices.getDevice(
752                 AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8(""), AUDIO_FORMAT_DEFAULT);
753         break;
754     case AUDIO_SOURCE_FM_TUNER:
755         device = availableDevices.getDevice(
756                 AUDIO_DEVICE_IN_FM_TUNER, String8(""), AUDIO_FORMAT_DEFAULT);
757         break;
758     case AUDIO_SOURCE_ECHO_REFERENCE:
759         device = availableDevices.getDevice(
760                 AUDIO_DEVICE_IN_ECHO_REFERENCE, String8(""), AUDIO_FORMAT_DEFAULT);
761         break;
762     case AUDIO_SOURCE_ULTRASOUND:
763         device = availableDevices.getFirstExistingDevice({
764                 AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BACK_MIC});
765         break;
766     default:
767         ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
768         break;
769     }
770     if (device == nullptr) {
771         ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
772         device = availableDevices.getDevice(
773                 AUDIO_DEVICE_IN_STUB, String8(""), AUDIO_FORMAT_DEFAULT);
774         ALOGE_IF(device == nullptr,
775                  "getDeviceForInputSource() no default device defined");
776     }
777 
778     ALOGV_IF(device != nullptr,
779              "getDeviceForInputSource()input source %d, device %08x",
780              inputSource, device->type());
781     return device;
782 }
783 
setStrategyDevices(const sp<ProductStrategy> & strategy,const DeviceVector & devices)784 void Engine::setStrategyDevices(const sp<ProductStrategy>& strategy, const DeviceVector &devices) {
785     strategy->setDeviceTypes(devices.types());
786     strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
787 }
788 
getProductStrategyFromLegacy(legacy_strategy legacyStrategy) const789 product_strategy_t Engine::getProductStrategyFromLegacy(legacy_strategy legacyStrategy) const {
790     for (const auto& strategyMap : mLegacyStrategyMap) {
791         if (strategyMap.second == legacyStrategy) {
792             return strategyMap.first;
793         }
794     }
795     return PRODUCT_STRATEGY_NONE;
796 }
797 
getPreferredDeviceTypeForLegacyStrategy(const DeviceVector & availableOutputDevices,legacy_strategy legacyStrategy) const798 audio_devices_t Engine::getPreferredDeviceTypeForLegacyStrategy(
799         const DeviceVector& availableOutputDevices, legacy_strategy legacyStrategy) const {
800     product_strategy_t strategy = getProductStrategyFromLegacy(legacyStrategy);
801     DeviceVector devices = getPreferredAvailableDevicesForProductStrategy(
802             availableOutputDevices, strategy);
803     if (devices.size() > 0) {
804         return devices[0]->type();
805     }
806     return AUDIO_DEVICE_NONE;
807 }
808 
getDevicesForProductStrategy(product_strategy_t strategy) const809 DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const {
810     const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();
811 
812     // Take context into account to remap product strategy before
813     // checking preferred device for strategy and applying default routing rules
814     strategy = remapStrategyFromContext(strategy, outputs);
815 
816     auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
817                           mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
818 
819     DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
820 
821     filterOutputDevicesForStrategy(legacyStrategy, availableOutputDevices, outputs);
822 
823     // check if this strategy has a preferred device that is available,
824     // if yes, give priority to it.
825     DeviceVector preferredAvailableDevVec =
826             getPreferredAvailableDevicesForProductStrategy(availableOutputDevices, strategy);
827     if (!preferredAvailableDevVec.isEmpty()) {
828         return preferredAvailableDevVec;
829     }
830 
831     // Remove all disabled devices from the available device list.
832     DeviceVector disabledDevVec =
833             getDisabledDevicesForProductStrategy(availableOutputDevices, strategy);
834     availableOutputDevices.remove(disabledDevVec);
835 
836     return getDevicesForStrategyInt(legacyStrategy,
837                                     availableOutputDevices,
838                                     outputs);
839 }
840 
getOutputDevicesForAttributes(const audio_attributes_t & attributes,const sp<DeviceDescriptor> & preferredDevice,bool fromCache) const841 DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
842                                                    const sp<DeviceDescriptor> &preferredDevice,
843                                                    bool fromCache) const
844 {
845     // First check for explict routing device
846     if (preferredDevice != nullptr) {
847         ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
848         return DeviceVector(preferredDevice);
849     }
850     product_strategy_t strategy = getProductStrategyForAttributes(attributes);
851     const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
852     const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
853     //
854     // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
855     // be by APM?
856     //
857     // Honor explicit routing requests only if all active clients have a preferred route in which
858     // case the last active client route is used
859     sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
860     if (device != nullptr) {
861         return DeviceVector(device);
862     }
863 
864     return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
865 }
866 
getOutputDevicesForStream(audio_stream_type_t stream,bool fromCache) const867 DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
868 {
869     auto attributes = getAttributesForStreamType(stream);
870     return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
871 }
872 
getInputDeviceForAttributes(const audio_attributes_t & attr,uid_t uid,audio_session_t session,sp<AudioPolicyMix> * mix) const873 sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
874                                                          uid_t uid,
875                                                          audio_session_t session,
876                                                          sp<AudioPolicyMix> *mix) const
877 {
878     const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
879     const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
880     const auto &inputs = getApmObserver()->getInputs();
881     std::string address;
882 
883     //
884     // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
885     // first as it used to be by APM?
886     //
887     // Honor explicit routing requests only if all active clients have a preferred route in which
888     // case the last active client route is used
889     sp<DeviceDescriptor> device =
890             findPreferredDevice(inputs, attr.source, availableInputDevices);
891     if (device != nullptr) {
892         return device;
893     }
894 
895     device = policyMixes.getDeviceAndMixForInputSource(attr,
896                                                        availableInputDevices,
897                                                        uid,
898                                                        session,
899                                                        mix);
900     if (device != nullptr) {
901         return device;
902     }
903 
904     device = getDeviceForInputSource(attr.source);
905     if (device == nullptr || !audio_is_remote_submix_device(device->type())) {
906         // Return immediately if the device is null or it is not a remote submix device.
907         return device;
908     }
909 
910     // For remote submix device, try to find the device by address.
911     address = "0";
912     std::size_t pos;
913     std::string tags { attr.tags };
914     if ((pos = tags.find("addr=")) != std::string::npos) {
915         address = tags.substr(pos + std::strlen("addr="));
916     }
917     return availableInputDevices.getDevice(device->type(),
918                                            String8(address.c_str()),
919                                            AUDIO_FORMAT_DEFAULT);
920 }
921 
922 } // namespace android::audio_policy
923