blob: 43023a8784f9a15826b921ebf271c1366ba3d8ad [file] [log] [blame]
François Gaffie2110e042015-03-24 08:41:51 +01001/*
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"
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -070028#include <android-base/macros.h>
François Gaffie2110e042015-03-24 08:41:51 +010029#include <AudioPolicyManagerObserver.h>
30#include <AudioPort.h>
31#include <IOProfile.h>
François Gaffiec005e562018-11-06 15:04:49 +010032#include <AudioIODescriptorInterface.h>
François Gaffie2110e042015-03-24 08:41:51 +010033#include <policy.h>
34#include <utils/String8.h>
35#include <utils/Log.h>
36
37namespace android
38{
39namespace audio_policy
40{
41
François Gaffiedc7553f2018-11-02 10:39:57 +010042struct legacy_strategy_map { const char *name; legacy_strategy id; };
43static const std::vector<legacy_strategy_map> gLegacyStrategy = {
44 { "STRATEGY_NONE", STRATEGY_NONE },
45 { "STRATEGY_MEDIA", STRATEGY_MEDIA },
46 { "STRATEGY_PHONE", STRATEGY_PHONE },
47 { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
48 { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
49 { "STRATEGY_DTMF", STRATEGY_DTMF },
50 { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
51 { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
52 { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
53 { "STRATEGY_REROUTING", STRATEGY_REROUTING },
54 { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
55};
56
François Gaffie2110e042015-03-24 08:41:51 +010057Engine::Engine()
François Gaffie2110e042015-03-24 08:41:51 +010058{
François Gaffiedc7553f2018-11-02 10:39:57 +010059 auto result = EngineBase::loadAudioPolicyEngineConfig();
60 ALOGE_IF(result.nbSkippedElement != 0,
61 "Policy Engine configuration is partially invalid, skipped %zu elements",
62 result.nbSkippedElement);
63
64 for (const auto &strategy : gLegacyStrategy) {
65 mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
François Gaffie2110e042015-03-24 08:41:51 +010066 }
67}
68
François Gaffie2110e042015-03-24 08:41:51 +010069status_t Engine::setPhoneState(audio_mode_t state)
70{
71 ALOGV("setPhoneState() state %d", state);
72
73 if (state < 0 || state >= AUDIO_MODE_CNT) {
74 ALOGW("setPhoneState() invalid state %d", state);
75 return BAD_VALUE;
76 }
77
François Gaffiedc7553f2018-11-02 10:39:57 +010078 if (state == getPhoneState()) {
François Gaffie2110e042015-03-24 08:41:51 +010079 ALOGW("setPhoneState() setting same state %d", state);
80 return BAD_VALUE;
81 }
82
83 // store previous phone state for management of sonification strategy below
François Gaffiedc7553f2018-11-02 10:39:57 +010084 int oldState = getPhoneState();
85 EngineBase::setPhoneState(state);
François Gaffied1ab2bd2015-12-02 18:20:06 +010086
François Gaffie2110e042015-03-24 08:41:51 +010087 if (!is_state_in_call(oldState) && is_state_in_call(state)) {
88 ALOGV(" Entering call in setPhoneState()");
François Gaffiedc7553f2018-11-02 10:39:57 +010089 getApmObserver()->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
François Gaffied1ab2bd2015-12-02 18:20:06 +010090 AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010091 } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
92 ALOGV(" Exiting call in setPhoneState()");
François Gaffiedc7553f2018-11-02 10:39:57 +010093 getApmObserver()->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010094 }
95 return NO_ERROR;
96}
97
98status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
99{
100 switch(usage) {
101 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
102 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
103 config != AUDIO_POLICY_FORCE_NONE) {
104 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
105 return BAD_VALUE;
106 }
François Gaffie2110e042015-03-24 08:41:51 +0100107 break;
108 case AUDIO_POLICY_FORCE_FOR_MEDIA:
109 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
110 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
111 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
112 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
113 config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
114 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
115 return BAD_VALUE;
116 }
François Gaffie2110e042015-03-24 08:41:51 +0100117 break;
118 case AUDIO_POLICY_FORCE_FOR_RECORD:
119 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
120 config != AUDIO_POLICY_FORCE_NONE) {
121 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
122 return BAD_VALUE;
123 }
François Gaffie2110e042015-03-24 08:41:51 +0100124 break;
125 case AUDIO_POLICY_FORCE_FOR_DOCK:
126 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
127 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
128 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
129 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
130 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
131 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
132 }
François Gaffie2110e042015-03-24 08:41:51 +0100133 break;
134 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
135 if (config != AUDIO_POLICY_FORCE_NONE &&
136 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
137 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
138 }
François Gaffie2110e042015-03-24 08:41:51 +0100139 break;
140 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
141 if (config != AUDIO_POLICY_FORCE_NONE &&
142 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
Phil Burk09bc4612016-02-24 15:58:15 -0800143 ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
144 }
Phil Burk09bc4612016-02-24 15:58:15 -0800145 break;
146 case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
147 if (config != AUDIO_POLICY_FORCE_NONE &&
148 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
jiabin81772902018-04-02 17:52:27 -0700149 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
150 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
Phil Burk09bc4612016-02-24 15:58:15 -0800151 ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
152 return BAD_VALUE;
François Gaffie2110e042015-03-24 08:41:51 +0100153 }
François Gaffie2110e042015-03-24 08:41:51 +0100154 break;
Jack He96117ae2018-02-12 20:52:53 -0800155 case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
156 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
157 ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
158 return BAD_VALUE;
159 }
Jack He96117ae2018-02-12 20:52:53 -0800160 break;
François Gaffie2110e042015-03-24 08:41:51 +0100161 default:
162 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800163 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100164 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100165 return EngineBase::setForceUse(usage, config);
François Gaffie2110e042015-03-24 08:41:51 +0100166}
167
François Gaffiedc7553f2018-11-02 10:39:57 +0100168audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
169 DeviceVector availableOutputDevices,
170 DeviceVector availableInputDevices,
171 const SwAudioOutputCollection &outputs,
172 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800173{
François Gaffie2110e042015-03-24 08:41:51 +0100174 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800175 uint32_t availableOutputDevicesType =
176 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100177
178 switch (strategy) {
179
180 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
181 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100182 break;
183
184 case STRATEGY_SONIFICATION_RESPECTFUL:
François Gaffie1c878552018-11-22 16:53:21 +0100185 if (isInCall() || outputs.isActiveLocally(streamToVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800186 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800187 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
188 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100189 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800190 bool media_active_locally =
François Gaffie1c878552018-11-22 16:53:21 +0100191 outputs.isActiveLocally(streamToVolumeSource(AUDIO_STREAM_MUSIC),
192 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
193 || outputs.isActiveLocally(
194 streamToVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
195 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800196 // routing is same as media without the "remote" device
197 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
198 availableOutputDevices,
199 availableInputDevices, outputs,
200 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
201 // if no media is playing on the device, check for mandatory use of "safe" speaker
202 // when media would have played on speaker, and the safe speaker path is available
203 if (!media_active_locally
204 && (device & AUDIO_DEVICE_OUT_SPEAKER)
205 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700206 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
207 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
208 }
François Gaffie2110e042015-03-24 08:41:51 +0100209 }
210 break;
211
212 case STRATEGY_DTMF:
213 if (!isInCall()) {
214 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800215 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800216 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
217 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100218 break;
219 }
220 // when in call, DTMF and PHONE strategies follow the same rules
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700221 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100222
223 case STRATEGY_PHONE:
224 // Force use of only devices on primary output if:
225 // - in call AND
226 // - cannot route from voice call RX OR
227 // - audio HAL version is < 3.0 and TX device is on the primary HW module
228 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
229 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
230 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
231 audio_devices_t availPrimaryInputDevices =
Mikhail Naganov93661932018-07-26 14:37:41 -0700232 availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800233
234 // TODO: getPrimaryOutput return only devices from first module in
235 // audio_policy_configuration.xml, hearing aid is not there, but it's
236 // a primary device
237 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100238 audio_devices_t availPrimaryOutputDevices =
François Gaffie11d30102018-11-02 16:09:09 +0100239 (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) &
Eric Laurent58a73fc2018-02-21 18:46:13 -0800240 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100241
242 if (((availableInputDevices.types() &
243 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
244 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700245 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100246 availableOutputDevicesType = availPrimaryOutputDevices;
247 }
248 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800249 // for phone strategy, we first consider the forced use and then the available devices by
250 // order of priority
François Gaffiedc7553f2018-11-02 10:39:57 +0100251 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100252 case AUDIO_POLICY_FORCE_BT_SCO:
253 if (!isInCall() || strategy != STRATEGY_DTMF) {
254 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
255 if (device) break;
256 }
257 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
258 if (device) break;
259 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
260 if (device) break;
261 // if SCO device is requested but no SCO device is available, fall back to default case
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700262 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100263
264 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800265 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
266 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100267 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
268 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100269 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800270 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100271 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
272 if (device) break;
273 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
274 if (device) break;
275 }
276 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
277 if (device) break;
278 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
279 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800280 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
281 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700282 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
283 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100284 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
285 if (device) break;
286 if (!isInCall()) {
287 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
288 if (device) break;
289 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
290 if (device) break;
291 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
292 if (device) break;
293 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
294 if (device) break;
295 }
296 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100297 break;
298
299 case AUDIO_POLICY_FORCE_SPEAKER:
300 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
301 // A2DP speaker when forcing to speaker output
302 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100303 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800304 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100305 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
306 if (device) break;
307 }
308 if (!isInCall()) {
309 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
310 if (device) break;
311 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
312 if (device) break;
313 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
314 if (device) break;
315 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
316 if (device) break;
317 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
318 if (device) break;
319 }
François Gaffie2110e042015-03-24 08:41:51 +0100320 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100321 break;
322 }
323 break;
324
325 case STRATEGY_SONIFICATION:
326
Eric Laurentdcd4ab12018-06-29 17:45:13 -0700327 // If incall, just select the STRATEGY_PHONE device
François Gaffie1c878552018-11-22 16:53:21 +0100328 if (isInCall() ||
329 outputs.isActiveLocally(streamToVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800330 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800331 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
332 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100333 break;
334 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700335 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100336
337 case STRATEGY_ENFORCED_AUDIBLE:
338 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
339 // except:
340 // - when in call where it doesn't default to STRATEGY_PHONE behavior
341 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
342
343 if ((strategy == STRATEGY_SONIFICATION) ||
François Gaffiedc7553f2018-11-02 10:39:57 +0100344 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
François Gaffie2110e042015-03-24 08:41:51 +0100345 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100346 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800347
348 // if SCO headset is connected and we are told to use it, play ringtone over
349 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800350 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800351 uint32_t device2 = AUDIO_DEVICE_NONE;
352 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
353 if (device2 == AUDIO_DEVICE_NONE) {
354 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
355 }
356 if (device2 == AUDIO_DEVICE_NONE) {
357 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
358 }
Jack He96117ae2018-02-12 20:52:53 -0800359 // Use ONLY Bluetooth SCO output when ringing in vibration mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100360 if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jack He96117ae2018-02-12 20:52:53 -0800361 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
François Gaffiedc7553f2018-11-02 10:39:57 +0100362 if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
Jack He96117ae2018-02-12 20:52:53 -0800363 == AUDIO_POLICY_FORCE_BT_SCO) {
364 if (device2 != AUDIO_DEVICE_NONE) {
365 device = device2;
366 break;
367 }
368 }
369 }
370 // Use both Bluetooth SCO and phone default output when ringing in normal mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100371 if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
juyuchen5fa0aed2018-05-16 10:58:37 +0800372 if ((strategy == STRATEGY_SONIFICATION) &&
373 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
374 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
375 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
376 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
377 }
Jack He96117ae2018-02-12 20:52:53 -0800378 if (device2 != AUDIO_DEVICE_NONE) {
379 device |= device2;
380 break;
381 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800382 }
383 }
François Gaffie2110e042015-03-24 08:41:51 +0100384 // The second device used for sonification is the same as the device used by media strategy
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700385 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100386
François Gaffie2110e042015-03-24 08:41:51 +0100387 case STRATEGY_ACCESSIBILITY:
388 if (strategy == STRATEGY_ACCESSIBILITY) {
389 // do not route accessibility prompts to a digital output currently configured with a
390 // compressed format as they would likely not be mixed and dropped.
391 for (size_t i = 0; i < outputs.size(); i++) {
392 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
François Gaffie11d30102018-11-02 16:09:09 +0100393 audio_devices_t devices = desc->devices().types() &
François Gaffie2110e042015-03-24 08:41:51 +0100394 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
395 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
396 devices != AUDIO_DEVICE_NONE) {
397 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
398 }
399 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800400 availableOutputDevices =
Mikhail Naganov708e0382018-05-30 09:53:04 -0700401 availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType);
François Gaffie1c878552018-11-22 16:53:21 +0100402 if (outputs.isActive(streamToVolumeSource(AUDIO_STREAM_RING)) ||
403 outputs.isActive(streamToVolumeSource(AUDIO_STREAM_ALARM))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800404 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800405 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
406 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800407 }
408 if (isInCall()) {
409 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800410 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
411 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800412 }
François Gaffie2110e042015-03-24 08:41:51 +0100413 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800414 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700415 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100416
Eric Laurent28d09f02016-03-08 10:43:05 -0800417 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100418 case STRATEGY_REROUTING:
419 case STRATEGY_MEDIA: {
420 uint32_t device2 = AUDIO_DEVICE_NONE;
421 if (strategy != STRATEGY_SONIFICATION) {
422 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800423 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Aniket Kumar Lata4e464702019-01-10 23:38:46 -0800424 String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100425 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
426 }
427 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700428 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800429 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800430 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
431 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700432 break;
433 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800434 if (device2 == AUDIO_DEVICE_NONE) {
435 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
436 }
François Gaffie2110e042015-03-24 08:41:51 +0100437 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100438 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800439 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100440 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
441 if (device2 == AUDIO_DEVICE_NONE) {
442 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
443 }
444 if (device2 == AUDIO_DEVICE_NONE) {
445 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
446 }
447 }
448 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100449 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
François Gaffie2110e042015-03-24 08:41:51 +0100450 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
451 }
452 if (device2 == AUDIO_DEVICE_NONE) {
453 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
454 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700455 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100456 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
457 }
458 if (device2 == AUDIO_DEVICE_NONE) {
459 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
460 }
461 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700462 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
463 }
464 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100465 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
466 }
467 if (device2 == AUDIO_DEVICE_NONE) {
468 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
469 }
470 if (device2 == AUDIO_DEVICE_NONE) {
471 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
472 }
473 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
474 // no sonification on aux digital (e.g. HDMI)
475 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
476 }
477 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100478 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
François Gaffie2110e042015-03-24 08:41:51 +0100479 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
480 }
481 if (device2 == AUDIO_DEVICE_NONE) {
482 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
483 }
484 int device3 = AUDIO_DEVICE_NONE;
485 if (strategy == STRATEGY_MEDIA) {
486 // ARC, SPDIF and AUX_LINE can co-exist with others.
487 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
488 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
489 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
490 }
491
492 device2 |= device3;
493 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
494 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
495 device |= device2;
496
497 // If hdmi system audio mode is on, remove speaker out of output list.
498 if ((strategy == STRATEGY_MEDIA) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100499 (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
François Gaffie2110e042015-03-24 08:41:51 +0100500 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
501 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
502 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700503
504 // for STRATEGY_SONIFICATION:
505 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
506 if ((strategy == STRATEGY_SONIFICATION) &&
507 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
508 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
509 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
510 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
511 }
François Gaffie2110e042015-03-24 08:41:51 +0100512 } break;
513
514 default:
515 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
516 break;
517 }
518
Eric Laurent5a2b6292016-04-14 18:05:57 -0700519 if (device == AUDIO_DEVICE_NONE) {
520 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
François Gaffiedc7553f2018-11-02 10:39:57 +0100521 device = getApmObserver()->getDefaultOutputDevice()->type();
Eric Laurent5a2b6292016-04-14 18:05:57 -0700522 ALOGE_IF(device == AUDIO_DEVICE_NONE,
523 "getDeviceForStrategy() no default device defined");
524 }
François Gaffie2110e042015-03-24 08:41:51 +0100525 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
526 return device;
527}
528
529
530audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
531{
François Gaffiedc7553f2018-11-02 10:39:57 +0100532 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
533 const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
534 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100535 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
536
537 uint32_t device = AUDIO_DEVICE_NONE;
538
Eric Laurentdc95a252018-04-12 12:46:56 -0700539 // 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:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800549 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700550 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
551 break;
552 default:
553 break;
554 }
555 }
556
François Gaffie2110e042015-03-24 08:41:51 +0100557 switch (inputSource) {
558 case AUDIO_SOURCE_VOICE_UPLINK:
559 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
560 device = AUDIO_DEVICE_IN_VOICE_CALL;
561 break;
562 }
563 break;
564
565 case AUDIO_SOURCE_DEFAULT:
566 case AUDIO_SOURCE_MIC:
567 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
568 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100569 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100570 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
571 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
572 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
573 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700574 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
575 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100576 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
577 device = AUDIO_DEVICE_IN_USB_DEVICE;
578 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
579 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
580 }
581 break;
582
583 case AUDIO_SOURCE_VOICE_COMMUNICATION:
584 // Allow only use of devices on primary input if in call and HAL does not support routing
585 // to voice call path.
586 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
587 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
588 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
Mikhail Naganov93661932018-07-26 14:37:41 -0700589 availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
590 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100591 }
592
François Gaffiedc7553f2018-11-02 10:39:57 +0100593 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100594 case AUDIO_POLICY_FORCE_BT_SCO:
595 // if SCO device is requested but no SCO device is available, fall back to default case
596 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
597 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
598 break;
599 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700600 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100601
602 default: // FORCE_NONE
603 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
604 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700605 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
606 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100607 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
608 device = AUDIO_DEVICE_IN_USB_DEVICE;
609 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
610 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
611 }
612 break;
613
614 case AUDIO_POLICY_FORCE_SPEAKER:
615 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
616 device = AUDIO_DEVICE_IN_BACK_MIC;
617 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
618 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
619 }
620 break;
621 }
622 break;
623
624 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800625 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100626 case AUDIO_SOURCE_HOTWORD:
François Gaffiedc7553f2018-11-02 10:39:57 +0100627 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100628 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
629 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
630 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
631 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700632 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
633 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100634 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
635 device = AUDIO_DEVICE_IN_USB_DEVICE;
636 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
637 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
638 }
639 break;
640 case AUDIO_SOURCE_CAMCORDER:
641 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
642 device = AUDIO_DEVICE_IN_BACK_MIC;
643 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
644 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900645 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
646 // This is specifically for a device without built-in mic
647 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100648 }
649 break;
650 case AUDIO_SOURCE_VOICE_DOWNLINK:
651 case AUDIO_SOURCE_VOICE_CALL:
652 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
653 device = AUDIO_DEVICE_IN_VOICE_CALL;
654 }
655 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800656 case AUDIO_SOURCE_VOICE_PERFORMANCE:
657 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
658 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
659 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
660 device = AUDIO_DEVICE_IN_USB_HEADSET;
661 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
662 device = AUDIO_DEVICE_IN_USB_DEVICE;
663 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
664 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
665 }
666 break;
François Gaffie2110e042015-03-24 08:41:51 +0100667 case AUDIO_SOURCE_REMOTE_SUBMIX:
668 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
669 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
670 }
671 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800672 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100673 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
674 device = AUDIO_DEVICE_IN_FM_TUNER;
675 }
676 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800677 case AUDIO_SOURCE_ECHO_REFERENCE:
678 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
679 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
680 }
681 break;
François Gaffie2110e042015-03-24 08:41:51 +0100682 default:
683 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
684 break;
685 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700686 if (device == AUDIO_DEVICE_NONE) {
687 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
688 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
689 device = AUDIO_DEVICE_IN_STUB;
690 }
691 ALOGE_IF(device == AUDIO_DEVICE_NONE,
692 "getDeviceForInputSource() no default device defined");
693 }
François Gaffie2110e042015-03-24 08:41:51 +0100694 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
695 return device;
696}
697
François Gaffiedc7553f2018-11-02 10:39:57 +0100698void Engine::updateDeviceSelectionCache()
699{
700 for (const auto &iter : getProductStrategies()) {
701 const auto &strategy = iter.second;
702 auto devices = getDevicesForProductStrategy(strategy->getId());
703 mDevicesForStrategies[strategy->getId()] = devices;
704 strategy->setDeviceTypes(devices.types());
705 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
706 }
707}
708
709DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
710{
711 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
712 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
713 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
714
715 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
716 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
717 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
718 availableOutputDevices,
719 availableInputDevices, outputs,
720 (uint32_t)AUDIO_DEVICE_NONE);
721 return availableOutputDevices.getDevicesFromTypeMask(devices);
722}
723
724DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
725 const sp<DeviceDescriptor> &preferredDevice,
726 bool fromCache) const
727{
728 // First check for explict routing device
729 if (preferredDevice != nullptr) {
730 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
731 return DeviceVector(preferredDevice);
732 }
François Gaffiec005e562018-11-06 15:04:49 +0100733 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
734 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
735 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100736 //
737 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
738 // be by APM?
739 //
François Gaffiec005e562018-11-06 15:04:49 +0100740 // Honor explicit routing requests only if all active clients have a preferred route in which
741 // case the last active client route is used
742 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
743 if (device != nullptr) {
744 return DeviceVector(device);
745 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100746
747 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
748}
749
750DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
751{
752 auto attributes = getAttributesForStreamType(stream);
753 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
754}
755
756sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
François Gaffiec005e562018-11-06 15:04:49 +0100757 AudioMix **mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100758{
François Gaffiec005e562018-11-06 15:04:49 +0100759 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
François Gaffiedc7553f2018-11-02 10:39:57 +0100760 const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100761 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100762 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100763
François Gaffiedc7553f2018-11-02 10:39:57 +0100764 //
François Gaffiec005e562018-11-06 15:04:49 +0100765 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
766 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100767 //
François Gaffiec005e562018-11-06 15:04:49 +0100768 // Honor explicit routing requests only if all active clients have a preferred route in which
769 // case the last active client route is used
770 sp<DeviceDescriptor> device =
771 findPreferredDevice(inputs, attr.source, availableInputDevices);
772 if (device != nullptr) {
773 return device;
774 }
775
776 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
777 if (device != nullptr) {
778 return device;
779 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100780 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
781
782 if (audio_is_remote_submix_device(deviceType)) {
783 address = "0";
784 std::size_t pos;
785 std::string tags { attr.tags };
786 if ((pos = tags.find("addr=")) != std::string::npos) {
787 address = tags.substr(pos + std::strlen("addr="));
788 }
789 }
790 return availableInputDevices.getDevice(deviceType,
791 String8(address.c_str()),
792 AUDIO_FORMAT_DEFAULT);
793}
794
François Gaffie2110e042015-03-24 08:41:51 +0100795template <>
796AudioPolicyManagerInterface *Engine::queryInterface()
797{
François Gaffiedc7553f2018-11-02 10:39:57 +0100798 return this;
François Gaffie2110e042015-03-24 08:41:51 +0100799}
800
801} // namespace audio_policy
802} // namespace android
803
804