• 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
39 {
40 namespace audio_policy
41 {
42 
43 struct legacy_strategy_map { const char *name; legacy_strategy id; };
getLegacyStrategy()44 static const std::vector<legacy_strategy_map>& getLegacyStrategy() {
45     static const std::vector<legacy_strategy_map> legacyStrategy = {
46         { "STRATEGY_NONE", STRATEGY_NONE },
47         { "STRATEGY_MEDIA", STRATEGY_MEDIA },
48         { "STRATEGY_PHONE", STRATEGY_PHONE },
49         { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
50         { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
51         { "STRATEGY_DTMF", STRATEGY_DTMF },
52         { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
53         { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
54         { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
55         { "STRATEGY_REROUTING", STRATEGY_REROUTING },
56         { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
57         { "STRATEGY_CALL_ASSISTANT", STRATEGY_CALL_ASSISTANT },
58     };
59     return legacyStrategy;
60 }
61 
Engine()62 Engine::Engine()
63 {
64     auto result = EngineBase::loadAudioPolicyEngineConfig();
65     ALOGE_IF(result.nbSkippedElement != 0,
66              "Policy Engine configuration is partially invalid, skipped %zu elements",
67              result.nbSkippedElement);
68 
69     auto legacyStrategy = getLegacyStrategy();
70     for (const auto &strategy : legacyStrategy) {
71         mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
72     }
73 }
74 
setForceUse(audio_policy_force_use_t usage,audio_policy_forced_cfg_t config)75 status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
76 {
77     switch(usage) {
78     case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
79         if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
80             config != AUDIO_POLICY_FORCE_NONE) {
81             ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
82             return BAD_VALUE;
83         }
84         break;
85     case AUDIO_POLICY_FORCE_FOR_MEDIA:
86         if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
87             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
88             config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
89             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
90             config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
91             ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
92             return BAD_VALUE;
93         }
94         break;
95     case AUDIO_POLICY_FORCE_FOR_RECORD:
96         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
97             config != AUDIO_POLICY_FORCE_NONE) {
98             ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
99             return BAD_VALUE;
100         }
101         break;
102     case AUDIO_POLICY_FORCE_FOR_DOCK:
103         if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
104             config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
105             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
106             config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
107             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
108             ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
109         }
110         break;
111     case AUDIO_POLICY_FORCE_FOR_SYSTEM:
112         if (config != AUDIO_POLICY_FORCE_NONE &&
113             config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
114             ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
115         }
116         break;
117     case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
118         if (config != AUDIO_POLICY_FORCE_NONE &&
119             config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
120             ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
121         }
122         break;
123     case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
124         if (config != AUDIO_POLICY_FORCE_NONE &&
125                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
126                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
127                 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
128             ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
129             return BAD_VALUE;
130         }
131         break;
132     case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
133         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
134             ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
135             return BAD_VALUE;
136         }
137         break;
138     default:
139         ALOGW("setForceUse() invalid usage %d", usage);
140         break; // TODO return BAD_VALUE?
141     }
142     return EngineBase::setForceUse(usage, config);
143 }
144 
getDevicesForStrategyInt(legacy_strategy strategy,DeviceVector availableOutputDevices,DeviceVector availableInputDevices,const SwAudioOutputCollection & outputs) const145 DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
146                                               DeviceVector availableOutputDevices,
147                                               DeviceVector availableInputDevices,
148                                               const SwAudioOutputCollection &outputs) const
149 {
150     DeviceVector devices;
151 
152     switch (strategy) {
153 
154     case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
155         devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
156         break;
157 
158     case STRATEGY_SONIFICATION_RESPECTFUL:
159         if (isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
160             devices = getDevicesForStrategyInt(
161                     STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
162         } else {
163             bool media_active_locally =
164                     outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_MUSIC),
165                                             SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
166                     || outputs.isActiveLocally(
167                         toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
168                         SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
169             // routing is same as media without the "remote" device
170             availableOutputDevices.remove(availableOutputDevices.getDevicesFromType(
171                     AUDIO_DEVICE_OUT_REMOTE_SUBMIX));
172             devices = getDevicesForStrategyInt(STRATEGY_MEDIA,
173                     availableOutputDevices,
174                     availableInputDevices, outputs);
175             // if no media is playing on the device, check for mandatory use of "safe" speaker
176             // when media would have played on speaker, and the safe speaker path is available
177             if (!media_active_locally) {
178                 devices.replaceDevicesByType(
179                         AUDIO_DEVICE_OUT_SPEAKER,
180                         availableOutputDevices.getDevicesFromType(
181                                 AUDIO_DEVICE_OUT_SPEAKER_SAFE));
182             }
183         }
184         break;
185 
186     case STRATEGY_DTMF:
187         if (!isInCall()) {
188             // when off call, DTMF strategy follows the same rules as MEDIA strategy
189             devices = getDevicesForStrategyInt(
190                     STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs);
191             break;
192         }
193         // when in call, DTMF and PHONE strategies follow the same rules
194         FALLTHROUGH_INTENDED;
195 
196     case STRATEGY_PHONE:
197         // Force use of only devices on primary output if:
198         // - in call AND
199         //   - cannot route from voice call RX OR
200         //   - audio HAL version is < 3.0 and TX device is on the primary HW module
201         if (getPhoneState() == AUDIO_MODE_IN_CALL) {
202             audio_devices_t txDevice = getDeviceForInputSource(
203                     AUDIO_SOURCE_VOICE_COMMUNICATION)->type();
204             sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
205             LOG_ALWAYS_FATAL_IF(primaryOutput == nullptr, "Primary output not found");
206             DeviceVector availPrimaryInputDevices =
207                     availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
208 
209             // TODO: getPrimaryOutput return only devices from first module in
210             // audio_policy_configuration.xml, hearing aid is not there, but it's
211             // a primary device
212             // FIXME: this is not the right way of solving this problem
213             DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypes(
214                     primaryOutput->supportedDevices().types());
215             availPrimaryOutputDevices.add(
216                     availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID));
217 
218             if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX,
219                     String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
220                     ((availPrimaryInputDevices.getDevice(
221                             txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
222                             (primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
223                 availableOutputDevices = availPrimaryOutputDevices;
224             }
225         }
226         // for phone strategy, we first consider the forced use and then the available devices by
227         // order of priority
228         switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
229         case AUDIO_POLICY_FORCE_BT_SCO:
230             if (!isInCall() || strategy != STRATEGY_DTMF) {
231                 devices = availableOutputDevices.getDevicesFromType(
232                         AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
233                 if (!devices.isEmpty()) break;
234             }
235             devices = availableOutputDevices.getFirstDevicesFromTypes({
236                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
237             if (!devices.isEmpty()) break;
238             // if SCO device is requested but no SCO device is available, fall back to default case
239             FALLTHROUGH_INTENDED;
240 
241         default:    // FORCE_NONE
242             devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
243             if (!devices.isEmpty()) break;
244             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
245             if (!isInCall() &&
246                     (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
247                      outputs.isA2dpSupported()) {
248                 devices = availableOutputDevices.getFirstDevicesFromTypes({
249                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
250                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES});
251                 if (!devices.isEmpty()) break;
252             }
253             devices = availableOutputDevices.getFirstDevicesFromTypes({
254                     AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADSET,
255                     AUDIO_DEVICE_OUT_LINE, AUDIO_DEVICE_OUT_USB_HEADSET,
256                     AUDIO_DEVICE_OUT_USB_DEVICE});
257             if (!devices.isEmpty()) break;
258             if (!isInCall()) {
259                 devices = availableOutputDevices.getFirstDevicesFromTypes({
260                         AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET,
261                         AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
262                 if (!devices.isEmpty()) break;
263             }
264             devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_EARPIECE);
265             break;
266 
267         case AUDIO_POLICY_FORCE_SPEAKER:
268             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
269             // A2DP speaker when forcing to speaker output
270             if (!isInCall() &&
271                     (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
272                      outputs.isA2dpSupported()) {
273                 devices = availableOutputDevices.getDevicesFromType(
274                         AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
275                 if (!devices.isEmpty()) break;
276             }
277             if (!isInCall()) {
278                 devices = availableOutputDevices.getFirstDevicesFromTypes({
279                         AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE,
280                         AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_AUX_DIGITAL,
281                         AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET});
282                 if (!devices.isEmpty()) break;
283             }
284             devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
285             break;
286         }
287     break;
288 
289     case STRATEGY_SONIFICATION:
290 
291         // If incall, just select the STRATEGY_PHONE device
292         if (isInCall() ||
293                 outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
294             devices = getDevicesForStrategyInt(
295                     STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
296             break;
297         }
298         FALLTHROUGH_INTENDED;
299 
300     case STRATEGY_ENFORCED_AUDIBLE:
301         // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
302         // except:
303         //   - when in call where it doesn't default to STRATEGY_PHONE behavior
304         //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
305 
306         if ((strategy == STRATEGY_SONIFICATION) ||
307                 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
308             devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
309         }
310 
311         // if SCO headset is connected and we are told to use it, play ringtone over
312         // speaker and BT SCO
313         if (!availableOutputDevices.getDevicesFromTypes(getAudioDeviceOutAllScoSet()).isEmpty()) {
314             DeviceVector devices2;
315             devices2 = availableOutputDevices.getFirstDevicesFromTypes({
316                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
317                     AUDIO_DEVICE_OUT_BLUETOOTH_SCO});
318             // Use ONLY Bluetooth SCO output when ringing in vibration mode
319             if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
320                     && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
321                 if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
322                         == AUDIO_POLICY_FORCE_BT_SCO) {
323                     if (!devices2.isEmpty()) {
324                         devices = devices2;
325                         break;
326                     }
327                 }
328             }
329             // Use both Bluetooth SCO and phone default output when ringing in normal mode
330             if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
331                 if (strategy == STRATEGY_SONIFICATION) {
332                     devices.replaceDevicesByType(
333                             AUDIO_DEVICE_OUT_SPEAKER,
334                             availableOutputDevices.getDevicesFromType(
335                                     AUDIO_DEVICE_OUT_SPEAKER_SAFE));
336                 }
337                 if (!devices2.isEmpty()) {
338                     devices.add(devices2);
339                     break;
340                 }
341             }
342         }
343         // The second device used for sonification is the same as the device used by media strategy
344         FALLTHROUGH_INTENDED;
345 
346     case STRATEGY_ACCESSIBILITY:
347         if (strategy == STRATEGY_ACCESSIBILITY) {
348             // do not route accessibility prompts to a digital output currently configured with a
349             // compressed format as they would likely not be mixed and dropped.
350             for (size_t i = 0; i < outputs.size(); i++) {
351                 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
352                 if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) {
353                     availableOutputDevices.remove(desc->devices().getDevicesFromTypes({
354                             AUDIO_DEVICE_OUT_HDMI, AUDIO_DEVICE_OUT_SPDIF,
355                             AUDIO_DEVICE_OUT_HDMI_ARC}));
356                 }
357             }
358             if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
359                     outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) {
360                 return getDevicesForStrategyInt(
361                     STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs);
362             }
363             if (isInCall()) {
364                 return getDevicesForStrategyInt(
365                         STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
366             }
367         }
368         // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
369         FALLTHROUGH_INTENDED;
370 
371     // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
372     case STRATEGY_REROUTING:
373     case STRATEGY_MEDIA: {
374         DeviceVector devices2;
375         if (strategy != STRATEGY_SONIFICATION) {
376             // no sonification on remote submix (e.g. WFD)
377             sp<DeviceDescriptor> remoteSubmix;
378             if ((remoteSubmix = availableOutputDevices.getDevice(
379                     AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"),
380                     AUDIO_FORMAT_DEFAULT)) != nullptr) {
381                 devices2.add(remoteSubmix);
382             }
383         }
384         if (isInCall() && (strategy == STRATEGY_MEDIA)) {
385             devices = getDevicesForStrategyInt(
386                     STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs);
387             break;
388         }
389         // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261).
390         if ((devices2.isEmpty()) &&
391                 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
392             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_HEARING_AID);
393         }
394         if ((devices2.isEmpty()) &&
395             (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
396             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
397         }
398         if (devices2.isEmpty() && (getLastRemovableMediaDevices().size() > 0)) {
399             if ((getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
400                     outputs.isA2dpSupported()) {
401                 // Get the last connected device of wired and bluetooth a2dp
402                 devices2 = availableOutputDevices.getFirstDevicesFromTypes(
403                         getLastRemovableMediaDevices());
404             } else {
405                 // Get the last connected device of wired except bluetooth a2dp
406                 devices2 = availableOutputDevices.getFirstDevicesFromTypes(
407                         getLastRemovableMediaDevices(GROUP_WIRED));
408             }
409         }
410         if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) {
411             // no sonification on aux digital (e.g. HDMI)
412             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_AUX_DIGITAL);
413         }
414         if ((devices2.isEmpty()) &&
415                 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
416             devices2 = availableOutputDevices.getDevicesFromType(
417                     AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
418         }
419         if (devices2.isEmpty()) {
420             devices2 = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER);
421         }
422         DeviceVector devices3;
423         if (strategy == STRATEGY_MEDIA) {
424             // ARC, SPDIF and AUX_LINE can co-exist with others.
425             devices3 = availableOutputDevices.getDevicesFromTypes({
426                     AUDIO_DEVICE_OUT_HDMI_ARC, AUDIO_DEVICE_OUT_SPDIF, AUDIO_DEVICE_OUT_AUX_LINE});
427         }
428 
429         devices2.add(devices3);
430         // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
431         // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
432         devices.add(devices2);
433 
434         // If hdmi system audio mode is on, remove speaker out of output list.
435         if ((strategy == STRATEGY_MEDIA) &&
436             (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
437                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
438             devices.remove(devices.getDevicesFromType(AUDIO_DEVICE_OUT_SPEAKER));
439         }
440 
441         // for STRATEGY_SONIFICATION:
442         // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
443         if (strategy == STRATEGY_SONIFICATION) {
444             devices.replaceDevicesByType(
445                     AUDIO_DEVICE_OUT_SPEAKER,
446                     availableOutputDevices.getDevicesFromType(
447                             AUDIO_DEVICE_OUT_SPEAKER_SAFE));
448         }
449         } break;
450 
451     case STRATEGY_CALL_ASSISTANT:
452         devices = availableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
453         break;
454 
455     default:
456         ALOGW("getDevicesForStrategy() unknown strategy: %d", strategy);
457         break;
458     }
459 
460     if (devices.isEmpty()) {
461         ALOGV("getDevicesForStrategy() no device found for strategy %d", strategy);
462         sp<DeviceDescriptor> defaultOutputDevice = getApmObserver()->getDefaultOutputDevice();
463         if (defaultOutputDevice != nullptr) {
464             devices.add(defaultOutputDevice);
465         }
466         ALOGE_IF(devices.isEmpty(),
467                  "getDevicesForStrategy() no default device defined");
468     }
469 
470     ALOGVV("getDevices ForStrategy() strategy %d, device %s",
471            strategy, dumpDeviceTypes(devices.types()).c_str());
472     return devices;
473 }
474 
475 
getDeviceForInputSource(audio_source_t inputSource) const476 sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const
477 {
478     const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
479     const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
480     const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
481     DeviceVector availableDevices = availableInputDevices;
482     sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
483     DeviceVector availablePrimaryDevices = primaryOutput == nullptr ? DeviceVector()
484             : availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
485     sp<DeviceDescriptor> device;
486 
487     // when a call is active, force device selection to match source VOICE_COMMUNICATION
488     // for most other input sources to avoid rerouting call TX audio
489     if (isInCall()) {
490         switch (inputSource) {
491         case AUDIO_SOURCE_DEFAULT:
492         case AUDIO_SOURCE_MIC:
493         case AUDIO_SOURCE_VOICE_RECOGNITION:
494         case AUDIO_SOURCE_UNPROCESSED:
495         case AUDIO_SOURCE_HOTWORD:
496         case AUDIO_SOURCE_CAMCORDER:
497         case AUDIO_SOURCE_VOICE_PERFORMANCE:
498             inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
499             break;
500         default:
501             break;
502         }
503     }
504 
505     switch (inputSource) {
506     case AUDIO_SOURCE_DEFAULT:
507     case AUDIO_SOURCE_MIC:
508         device = availableDevices.getDevice(
509                 AUDIO_DEVICE_IN_BLUETOOTH_A2DP, String8(""), AUDIO_FORMAT_DEFAULT);
510         if (device != nullptr) break;
511         if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) {
512             device = availableDevices.getDevice(
513                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
514             if (device != nullptr) break;
515         }
516         device = availableDevices.getFirstExistingDevice({
517                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
518                 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
519         break;
520 
521     case AUDIO_SOURCE_VOICE_COMMUNICATION:
522         // Allow only use of devices on primary input if in call and HAL does not support routing
523         // to voice call path.
524         if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
525                 (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX,
526                         String8(""), AUDIO_FORMAT_DEFAULT)) == nullptr) {
527             LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
528             availableDevices = availablePrimaryDevices;
529         }
530 
531         switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
532         case AUDIO_POLICY_FORCE_BT_SCO:
533             // if SCO device is requested but no SCO device is available, fall back to default case
534             device = availableDevices.getDevice(
535                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
536             if (device != nullptr) {
537                 break;
538             }
539             FALLTHROUGH_INTENDED;
540 
541         default:    // FORCE_NONE
542             device = availableDevices.getFirstExistingDevice({
543                     AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
544                     AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
545             break;
546 
547         case AUDIO_POLICY_FORCE_SPEAKER:
548             device = availableDevices.getFirstExistingDevice({
549                     AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC});
550             break;
551         }
552         break;
553 
554     case AUDIO_SOURCE_VOICE_RECOGNITION:
555     case AUDIO_SOURCE_UNPROCESSED:
556     case AUDIO_SOURCE_HOTWORD:
557         if (inputSource == AUDIO_SOURCE_HOTWORD) {
558             // We should not use primary output criteria for Hotword but rather limit
559             // to devices attached to the same HW module as the build in mic
560             LOG_ALWAYS_FATAL_IF(availablePrimaryDevices.isEmpty(), "Primary devices not found");
561             availableDevices = availablePrimaryDevices;
562         }
563         if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) {
564             device = availableDevices.getDevice(
565                     AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT);
566             if (device != nullptr) break;
567         }
568         device = availableDevices.getFirstExistingDevice({
569                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
570                 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
571         break;
572     case AUDIO_SOURCE_CAMCORDER:
573         // For a device without built-in mic, adding usb device
574         device = availableDevices.getFirstExistingDevice({
575                 AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC,
576                 AUDIO_DEVICE_IN_USB_DEVICE});
577         break;
578     case AUDIO_SOURCE_VOICE_DOWNLINK:
579     case AUDIO_SOURCE_VOICE_CALL:
580     case AUDIO_SOURCE_VOICE_UPLINK:
581         device = availableDevices.getDevice(
582                 AUDIO_DEVICE_IN_VOICE_CALL, String8(""), AUDIO_FORMAT_DEFAULT);
583         break;
584     case AUDIO_SOURCE_VOICE_PERFORMANCE:
585         device = availableDevices.getFirstExistingDevice({
586                 AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET,
587                 AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC});
588         break;
589     case AUDIO_SOURCE_REMOTE_SUBMIX:
590         device = availableDevices.getDevice(
591                 AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8(""), AUDIO_FORMAT_DEFAULT);
592         break;
593     case AUDIO_SOURCE_FM_TUNER:
594         device = availableDevices.getDevice(
595                 AUDIO_DEVICE_IN_FM_TUNER, String8(""), AUDIO_FORMAT_DEFAULT);
596         break;
597     case AUDIO_SOURCE_ECHO_REFERENCE:
598         device = availableDevices.getDevice(
599                 AUDIO_DEVICE_IN_ECHO_REFERENCE, String8(""), AUDIO_FORMAT_DEFAULT);
600         break;
601     default:
602         ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
603         break;
604     }
605     if (device == nullptr) {
606         ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
607         device = availableDevices.getDevice(
608                 AUDIO_DEVICE_IN_STUB, String8(""), AUDIO_FORMAT_DEFAULT);
609         ALOGE_IF(device == nullptr,
610                  "getDeviceForInputSource() no default device defined");
611     }
612     ALOGV_IF(device != nullptr,
613              "getDeviceForInputSource()input source %d, device %08x",
614              inputSource, device->type());
615     return device;
616 }
617 
updateDeviceSelectionCache()618 void Engine::updateDeviceSelectionCache()
619 {
620     for (const auto &iter : getProductStrategies()) {
621         const auto& strategy = iter.second;
622         auto devices = getDevicesForProductStrategy(strategy->getId());
623         mDevicesForStrategies[strategy->getId()] = devices;
624         strategy->setDeviceTypes(devices.types());
625         strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
626     }
627 }
628 
getDevicesForProductStrategy(product_strategy_t strategy) const629 DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const {
630     DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
631 
632     // check if this strategy has a preferred device that is available,
633     // if yes, give priority to it
634     AudioDeviceTypeAddr preferredStrategyDevice;
635     const status_t status = getPreferredDeviceForStrategy(strategy, preferredStrategyDevice);
636     if (status == NO_ERROR) {
637         // there is a preferred device, is it available?
638         sp<DeviceDescriptor> preferredAvailableDevDescr = availableOutputDevices.getDevice(
639                 preferredStrategyDevice.mType,
640                 String8(preferredStrategyDevice.mAddress.c_str()),
641                 AUDIO_FORMAT_DEFAULT);
642         if (preferredAvailableDevDescr != nullptr) {
643             ALOGVV("%s using pref device 0x%08x/%s for strategy %u",
644                    __func__, preferredStrategyDevice.mType,
645                    preferredStrategyDevice.mAddress.c_str(), strategy);
646             return DeviceVector(preferredAvailableDevDescr);
647         }
648     }
649 
650     DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
651     const SwAudioOutputCollection& outputs = getApmObserver()->getOutputs();
652     auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
653                           mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
654     return getDevicesForStrategyInt(legacyStrategy,
655                                     availableOutputDevices,
656                                     availableInputDevices, outputs);
657 }
658 
getOutputDevicesForAttributes(const audio_attributes_t & attributes,const sp<DeviceDescriptor> & preferredDevice,bool fromCache) const659 DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
660                                                    const sp<DeviceDescriptor> &preferredDevice,
661                                                    bool fromCache) const
662 {
663     // First check for explict routing device
664     if (preferredDevice != nullptr) {
665         ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
666         return DeviceVector(preferredDevice);
667     }
668     product_strategy_t strategy = getProductStrategyForAttributes(attributes);
669     const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
670     const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
671     //
672     // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
673     // be by APM?
674     //
675     // Honor explicit routing requests only if all active clients have a preferred route in which
676     // case the last active client route is used
677     sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
678     if (device != nullptr) {
679         return DeviceVector(device);
680     }
681 
682     return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
683 }
684 
getOutputDevicesForStream(audio_stream_type_t stream,bool fromCache) const685 DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
686 {
687     auto attributes = getAttributesForStreamType(stream);
688     return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
689 }
690 
getInputDeviceForAttributes(const audio_attributes_t & attr,sp<AudioPolicyMix> * mix) const691 sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
692                                                          sp<AudioPolicyMix> *mix) const
693 {
694     const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
695     const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
696     const auto &inputs = getApmObserver()->getInputs();
697     std::string address;
698 
699     //
700     // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
701     // first as it used to be by APM?
702     //
703     // Honor explicit routing requests only if all active clients have a preferred route in which
704     // case the last active client route is used
705     sp<DeviceDescriptor> device =
706             findPreferredDevice(inputs, attr.source, availableInputDevices);
707     if (device != nullptr) {
708         return device;
709     }
710 
711     device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
712     if (device != nullptr) {
713         return device;
714     }
715 
716     device = getDeviceForInputSource(attr.source);
717     if (device == nullptr || !audio_is_remote_submix_device(device->type())) {
718         // Return immediately if the device is null or it is not a remote submix device.
719         return device;
720     }
721 
722     // For remote submix device, try to find the device by address.
723     address = "0";
724     std::size_t pos;
725     std::string tags { attr.tags };
726     if ((pos = tags.find("addr=")) != std::string::npos) {
727         address = tags.substr(pos + std::strlen("addr="));
728     }
729     return availableInputDevices.getDevice(device->type(),
730                                            String8(address.c_str()),
731                                            AUDIO_FORMAT_DEFAULT);
732 }
733 
734 } // namespace audio_policy
735 } // namespace android
736 
737 
738