blob: 93af8a6725df9a10303757a82c3efec45819831c [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:
Eric Laurent7731b5a2018-04-06 15:47:22 -0700185 if (isInCall() || outputs.isStreamActiveLocally(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 =
191 outputs.isStreamActiveLocally(
192 AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
193 || outputs.isStreamActiveLocally(
194 AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
195 // routing is same as media without the "remote" device
196 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
197 availableOutputDevices,
198 availableInputDevices, outputs,
199 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
200 // if no media is playing on the device, check for mandatory use of "safe" speaker
201 // when media would have played on speaker, and the safe speaker path is available
202 if (!media_active_locally
203 && (device & AUDIO_DEVICE_OUT_SPEAKER)
204 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700205 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
206 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
207 }
François Gaffie2110e042015-03-24 08:41:51 +0100208 }
209 break;
210
211 case STRATEGY_DTMF:
212 if (!isInCall()) {
213 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800214 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800215 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
216 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100217 break;
218 }
219 // when in call, DTMF and PHONE strategies follow the same rules
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700220 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100221
222 case STRATEGY_PHONE:
223 // Force use of only devices on primary output if:
224 // - in call AND
225 // - cannot route from voice call RX OR
226 // - audio HAL version is < 3.0 and TX device is on the primary HW module
227 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
228 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
229 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
230 audio_devices_t availPrimaryInputDevices =
Mikhail Naganov93661932018-07-26 14:37:41 -0700231 availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800232
233 // TODO: getPrimaryOutput return only devices from first module in
234 // audio_policy_configuration.xml, hearing aid is not there, but it's
235 // a primary device
236 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100237 audio_devices_t availPrimaryOutputDevices =
François Gaffie11d30102018-11-02 16:09:09 +0100238 (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) &
Eric Laurent58a73fc2018-02-21 18:46:13 -0800239 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100240
241 if (((availableInputDevices.types() &
242 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
243 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700244 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100245 availableOutputDevicesType = availPrimaryOutputDevices;
246 }
247 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800248 // for phone strategy, we first consider the forced use and then the available devices by
249 // order of priority
François Gaffiedc7553f2018-11-02 10:39:57 +0100250 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100251 case AUDIO_POLICY_FORCE_BT_SCO:
252 if (!isInCall() || strategy != STRATEGY_DTMF) {
253 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
254 if (device) break;
255 }
256 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
257 if (device) break;
258 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
259 if (device) break;
260 // if SCO device is requested but no SCO device is available, fall back to default case
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700261 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100262
263 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800264 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
265 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100266 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
267 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100268 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800269 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100270 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
271 if (device) break;
272 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
273 if (device) break;
274 }
275 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
276 if (device) break;
277 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
278 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800279 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
280 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700281 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
282 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100283 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
284 if (device) break;
285 if (!isInCall()) {
286 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
287 if (device) break;
288 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
289 if (device) break;
290 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
291 if (device) break;
292 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
293 if (device) break;
294 }
295 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100296 break;
297
298 case AUDIO_POLICY_FORCE_SPEAKER:
299 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
300 // A2DP speaker when forcing to speaker output
301 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100302 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800303 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100304 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
305 if (device) break;
306 }
307 if (!isInCall()) {
308 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
309 if (device) break;
310 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
311 if (device) break;
312 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
313 if (device) break;
314 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
315 if (device) break;
316 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
317 if (device) break;
318 }
François Gaffie2110e042015-03-24 08:41:51 +0100319 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100320 break;
321 }
322 break;
323
324 case STRATEGY_SONIFICATION:
325
Eric Laurentdcd4ab12018-06-29 17:45:13 -0700326 // If incall, just select the STRATEGY_PHONE device
Eric Laurent7731b5a2018-04-06 15:47:22 -0700327 if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800328 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800329 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
330 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100331 break;
332 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700333 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100334
335 case STRATEGY_ENFORCED_AUDIBLE:
336 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
337 // except:
338 // - when in call where it doesn't default to STRATEGY_PHONE behavior
339 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
340
341 if ((strategy == STRATEGY_SONIFICATION) ||
François Gaffiedc7553f2018-11-02 10:39:57 +0100342 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
François Gaffie2110e042015-03-24 08:41:51 +0100343 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100344 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800345
346 // if SCO headset is connected and we are told to use it, play ringtone over
347 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800348 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800349 uint32_t device2 = AUDIO_DEVICE_NONE;
350 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
351 if (device2 == AUDIO_DEVICE_NONE) {
352 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
353 }
354 if (device2 == AUDIO_DEVICE_NONE) {
355 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
356 }
Jack He96117ae2018-02-12 20:52:53 -0800357 // Use ONLY Bluetooth SCO output when ringing in vibration mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100358 if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jack He96117ae2018-02-12 20:52:53 -0800359 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
François Gaffiedc7553f2018-11-02 10:39:57 +0100360 if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
Jack He96117ae2018-02-12 20:52:53 -0800361 == AUDIO_POLICY_FORCE_BT_SCO) {
362 if (device2 != AUDIO_DEVICE_NONE) {
363 device = device2;
364 break;
365 }
366 }
367 }
368 // Use both Bluetooth SCO and phone default output when ringing in normal mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100369 if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
juyuchen5fa0aed2018-05-16 10:58:37 +0800370 if ((strategy == STRATEGY_SONIFICATION) &&
371 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
372 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
373 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
374 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
375 }
Jack He96117ae2018-02-12 20:52:53 -0800376 if (device2 != AUDIO_DEVICE_NONE) {
377 device |= device2;
378 break;
379 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800380 }
381 }
François Gaffie2110e042015-03-24 08:41:51 +0100382 // The second device used for sonification is the same as the device used by media strategy
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700383 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100384
François Gaffie2110e042015-03-24 08:41:51 +0100385 case STRATEGY_ACCESSIBILITY:
386 if (strategy == STRATEGY_ACCESSIBILITY) {
387 // do not route accessibility prompts to a digital output currently configured with a
388 // compressed format as they would likely not be mixed and dropped.
389 for (size_t i = 0; i < outputs.size(); i++) {
390 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
François Gaffie11d30102018-11-02 16:09:09 +0100391 audio_devices_t devices = desc->devices().types() &
François Gaffie2110e042015-03-24 08:41:51 +0100392 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
393 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
394 devices != AUDIO_DEVICE_NONE) {
395 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
396 }
397 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800398 availableOutputDevices =
Mikhail Naganov708e0382018-05-30 09:53:04 -0700399 availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType);
Eric Laurent28d09f02016-03-08 10:43:05 -0800400 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
401 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
402 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800403 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
404 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800405 }
406 if (isInCall()) {
407 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800408 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
409 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800410 }
François Gaffie2110e042015-03-24 08:41:51 +0100411 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800412 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700413 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100414
Eric Laurent28d09f02016-03-08 10:43:05 -0800415 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100416 case STRATEGY_REROUTING:
417 case STRATEGY_MEDIA: {
418 uint32_t device2 = AUDIO_DEVICE_NONE;
419 if (strategy != STRATEGY_SONIFICATION) {
420 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800421 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Aniket Kumar Lata4e464702019-01-10 23:38:46 -0800422 String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100423 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
424 }
425 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700426 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800427 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800428 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
429 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700430 break;
431 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800432 if (device2 == AUDIO_DEVICE_NONE) {
433 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
434 }
François Gaffie2110e042015-03-24 08:41:51 +0100435 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100436 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800437 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100438 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
439 if (device2 == AUDIO_DEVICE_NONE) {
440 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
441 }
442 if (device2 == AUDIO_DEVICE_NONE) {
443 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
444 }
445 }
446 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100447 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
François Gaffie2110e042015-03-24 08:41:51 +0100448 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
449 }
450 if (device2 == AUDIO_DEVICE_NONE) {
451 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
452 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700453 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100454 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
455 }
456 if (device2 == AUDIO_DEVICE_NONE) {
457 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
458 }
459 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700460 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
461 }
462 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100463 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
464 }
465 if (device2 == AUDIO_DEVICE_NONE) {
466 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
467 }
468 if (device2 == AUDIO_DEVICE_NONE) {
469 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
470 }
471 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
472 // no sonification on aux digital (e.g. HDMI)
473 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
474 }
475 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100476 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
François Gaffie2110e042015-03-24 08:41:51 +0100477 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
478 }
479 if (device2 == AUDIO_DEVICE_NONE) {
480 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
481 }
482 int device3 = AUDIO_DEVICE_NONE;
483 if (strategy == STRATEGY_MEDIA) {
484 // ARC, SPDIF and AUX_LINE can co-exist with others.
485 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
486 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
487 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
488 }
489
490 device2 |= device3;
491 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
492 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
493 device |= device2;
494
495 // If hdmi system audio mode is on, remove speaker out of output list.
496 if ((strategy == STRATEGY_MEDIA) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100497 (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
François Gaffie2110e042015-03-24 08:41:51 +0100498 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
499 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
500 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700501
502 // for STRATEGY_SONIFICATION:
503 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
504 if ((strategy == STRATEGY_SONIFICATION) &&
505 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
506 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
507 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
508 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
509 }
François Gaffie2110e042015-03-24 08:41:51 +0100510 } break;
511
512 default:
513 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
514 break;
515 }
516
Eric Laurent5a2b6292016-04-14 18:05:57 -0700517 if (device == AUDIO_DEVICE_NONE) {
518 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
François Gaffiedc7553f2018-11-02 10:39:57 +0100519 device = getApmObserver()->getDefaultOutputDevice()->type();
Eric Laurent5a2b6292016-04-14 18:05:57 -0700520 ALOGE_IF(device == AUDIO_DEVICE_NONE,
521 "getDeviceForStrategy() no default device defined");
522 }
François Gaffie2110e042015-03-24 08:41:51 +0100523 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
524 return device;
525}
526
527
528audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
529{
François Gaffiedc7553f2018-11-02 10:39:57 +0100530 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
531 const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
532 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100533 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
534
535 uint32_t device = AUDIO_DEVICE_NONE;
536
Eric Laurentdc95a252018-04-12 12:46:56 -0700537 // when a call is active, force device selection to match source VOICE_COMMUNICATION
538 // for most other input sources to avoid rerouting call TX audio
539 if (isInCall()) {
540 switch (inputSource) {
541 case AUDIO_SOURCE_DEFAULT:
542 case AUDIO_SOURCE_MIC:
543 case AUDIO_SOURCE_VOICE_RECOGNITION:
544 case AUDIO_SOURCE_UNPROCESSED:
545 case AUDIO_SOURCE_HOTWORD:
546 case AUDIO_SOURCE_CAMCORDER:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800547 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700548 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
549 break;
550 default:
551 break;
552 }
553 }
554
François Gaffie2110e042015-03-24 08:41:51 +0100555 switch (inputSource) {
556 case AUDIO_SOURCE_VOICE_UPLINK:
557 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
558 device = AUDIO_DEVICE_IN_VOICE_CALL;
559 break;
560 }
561 break;
562
563 case AUDIO_SOURCE_DEFAULT:
564 case AUDIO_SOURCE_MIC:
565 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
566 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100567 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100568 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
569 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
570 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
571 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700572 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
573 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100574 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
575 device = AUDIO_DEVICE_IN_USB_DEVICE;
576 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
577 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
578 }
579 break;
580
581 case AUDIO_SOURCE_VOICE_COMMUNICATION:
582 // Allow only use of devices on primary input if in call and HAL does not support routing
583 // to voice call path.
584 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
585 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
586 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
Mikhail Naganov93661932018-07-26 14:37:41 -0700587 availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
588 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100589 }
590
François Gaffiedc7553f2018-11-02 10:39:57 +0100591 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100592 case AUDIO_POLICY_FORCE_BT_SCO:
593 // if SCO device is requested but no SCO device is available, fall back to default case
594 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
595 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
596 break;
597 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700598 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100599
600 default: // FORCE_NONE
601 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
602 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700603 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
604 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100605 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
606 device = AUDIO_DEVICE_IN_USB_DEVICE;
607 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
608 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
609 }
610 break;
611
612 case AUDIO_POLICY_FORCE_SPEAKER:
613 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
614 device = AUDIO_DEVICE_IN_BACK_MIC;
615 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
616 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
617 }
618 break;
619 }
620 break;
621
622 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800623 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100624 case AUDIO_SOURCE_HOTWORD:
François Gaffiedc7553f2018-11-02 10:39:57 +0100625 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100626 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
627 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
628 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
629 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700630 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
631 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100632 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
633 device = AUDIO_DEVICE_IN_USB_DEVICE;
634 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
635 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
636 }
637 break;
638 case AUDIO_SOURCE_CAMCORDER:
639 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
640 device = AUDIO_DEVICE_IN_BACK_MIC;
641 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
642 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900643 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
644 // This is specifically for a device without built-in mic
645 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100646 }
647 break;
648 case AUDIO_SOURCE_VOICE_DOWNLINK:
649 case AUDIO_SOURCE_VOICE_CALL:
650 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
651 device = AUDIO_DEVICE_IN_VOICE_CALL;
652 }
653 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800654 case AUDIO_SOURCE_VOICE_PERFORMANCE:
655 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
656 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
657 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
658 device = AUDIO_DEVICE_IN_USB_HEADSET;
659 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
660 device = AUDIO_DEVICE_IN_USB_DEVICE;
661 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
662 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
663 }
664 break;
François Gaffie2110e042015-03-24 08:41:51 +0100665 case AUDIO_SOURCE_REMOTE_SUBMIX:
666 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
667 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
668 }
669 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800670 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100671 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
672 device = AUDIO_DEVICE_IN_FM_TUNER;
673 }
674 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800675 case AUDIO_SOURCE_ECHO_REFERENCE:
676 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
677 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
678 }
679 break;
François Gaffie2110e042015-03-24 08:41:51 +0100680 default:
681 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
682 break;
683 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700684 if (device == AUDIO_DEVICE_NONE) {
685 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
686 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
687 device = AUDIO_DEVICE_IN_STUB;
688 }
689 ALOGE_IF(device == AUDIO_DEVICE_NONE,
690 "getDeviceForInputSource() no default device defined");
691 }
François Gaffie2110e042015-03-24 08:41:51 +0100692 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
693 return device;
694}
695
François Gaffiedc7553f2018-11-02 10:39:57 +0100696void Engine::updateDeviceSelectionCache()
697{
698 for (const auto &iter : getProductStrategies()) {
699 const auto &strategy = iter.second;
700 auto devices = getDevicesForProductStrategy(strategy->getId());
701 mDevicesForStrategies[strategy->getId()] = devices;
702 strategy->setDeviceTypes(devices.types());
703 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
704 }
705}
706
707DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
708{
709 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
710 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
711 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
712
713 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
714 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
715 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
716 availableOutputDevices,
717 availableInputDevices, outputs,
718 (uint32_t)AUDIO_DEVICE_NONE);
719 return availableOutputDevices.getDevicesFromTypeMask(devices);
720}
721
722DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
723 const sp<DeviceDescriptor> &preferredDevice,
724 bool fromCache) const
725{
726 // First check for explict routing device
727 if (preferredDevice != nullptr) {
728 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
729 return DeviceVector(preferredDevice);
730 }
François Gaffiec005e562018-11-06 15:04:49 +0100731 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
732 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
733 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100734 //
735 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
736 // be by APM?
737 //
François Gaffiec005e562018-11-06 15:04:49 +0100738 // Honor explicit routing requests only if all active clients have a preferred route in which
739 // case the last active client route is used
740 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
741 if (device != nullptr) {
742 return DeviceVector(device);
743 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100744
745 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
746}
747
748DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
749{
750 auto attributes = getAttributesForStreamType(stream);
751 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
752}
753
754sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
François Gaffiec005e562018-11-06 15:04:49 +0100755 AudioMix **mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100756{
François Gaffiec005e562018-11-06 15:04:49 +0100757 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
François Gaffiedc7553f2018-11-02 10:39:57 +0100758 const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100759 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100760 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100761
François Gaffiedc7553f2018-11-02 10:39:57 +0100762 //
François Gaffiec005e562018-11-06 15:04:49 +0100763 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
764 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100765 //
François Gaffiec005e562018-11-06 15:04:49 +0100766 // Honor explicit routing requests only if all active clients have a preferred route in which
767 // case the last active client route is used
768 sp<DeviceDescriptor> device =
769 findPreferredDevice(inputs, attr.source, availableInputDevices);
770 if (device != nullptr) {
771 return device;
772 }
773
774 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
775 if (device != nullptr) {
776 return device;
777 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100778 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
779
780 if (audio_is_remote_submix_device(deviceType)) {
781 address = "0";
782 std::size_t pos;
783 std::string tags { attr.tags };
784 if ((pos = tags.find("addr=")) != std::string::npos) {
785 address = tags.substr(pos + std::strlen("addr="));
786 }
787 }
788 return availableInputDevices.getDevice(deviceType,
789 String8(address.c_str()),
790 AUDIO_FORMAT_DEFAULT);
791}
792
François Gaffie2110e042015-03-24 08:41:51 +0100793template <>
794AudioPolicyManagerInterface *Engine::queryInterface()
795{
François Gaffiedc7553f2018-11-02 10:39:57 +0100796 return this;
François Gaffie2110e042015-03-24 08:41:51 +0100797}
798
799} // namespace audio_policy
800} // namespace android
801
802