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