blob: c602f3a19e55ebdb3f6766082d2502d88fee56f2 [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::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
70{
71 switch(usage) {
72 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
73 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
74 config != AUDIO_POLICY_FORCE_NONE) {
75 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
76 return BAD_VALUE;
77 }
François Gaffie2110e042015-03-24 08:41:51 +010078 break;
79 case AUDIO_POLICY_FORCE_FOR_MEDIA:
80 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
81 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
82 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
83 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
84 config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
85 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
86 return BAD_VALUE;
87 }
François Gaffie2110e042015-03-24 08:41:51 +010088 break;
89 case AUDIO_POLICY_FORCE_FOR_RECORD:
90 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
91 config != AUDIO_POLICY_FORCE_NONE) {
92 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
93 return BAD_VALUE;
94 }
François Gaffie2110e042015-03-24 08:41:51 +010095 break;
96 case AUDIO_POLICY_FORCE_FOR_DOCK:
97 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
98 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
99 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
100 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
101 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
102 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
103 }
François Gaffie2110e042015-03-24 08:41:51 +0100104 break;
105 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
106 if (config != AUDIO_POLICY_FORCE_NONE &&
107 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
108 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
109 }
François Gaffie2110e042015-03-24 08:41:51 +0100110 break;
111 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
112 if (config != AUDIO_POLICY_FORCE_NONE &&
113 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
Phil Burk09bc4612016-02-24 15:58:15 -0800114 ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
115 }
Phil Burk09bc4612016-02-24 15:58:15 -0800116 break;
117 case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
118 if (config != AUDIO_POLICY_FORCE_NONE &&
119 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
jiabin81772902018-04-02 17:52:27 -0700120 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
121 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
Phil Burk09bc4612016-02-24 15:58:15 -0800122 ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
123 return BAD_VALUE;
François Gaffie2110e042015-03-24 08:41:51 +0100124 }
François Gaffie2110e042015-03-24 08:41:51 +0100125 break;
Jack He96117ae2018-02-12 20:52:53 -0800126 case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
127 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
128 ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
129 return BAD_VALUE;
130 }
Jack He96117ae2018-02-12 20:52:53 -0800131 break;
François Gaffie2110e042015-03-24 08:41:51 +0100132 default:
133 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800134 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100135 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100136 return EngineBase::setForceUse(usage, config);
François Gaffie2110e042015-03-24 08:41:51 +0100137}
138
François Gaffiedc7553f2018-11-02 10:39:57 +0100139audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
140 DeviceVector availableOutputDevices,
141 DeviceVector availableInputDevices,
142 const SwAudioOutputCollection &outputs,
143 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800144{
François Gaffie2110e042015-03-24 08:41:51 +0100145 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800146 uint32_t availableOutputDevicesType =
147 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100148
149 switch (strategy) {
150
151 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
152 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100153 break;
154
155 case STRATEGY_SONIFICATION_RESPECTFUL:
Eric Laurent83d17c22019-04-02 17:10:01 -0700156 if (isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800157 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800158 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
159 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100160 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800161 bool media_active_locally =
Eric Laurent83d17c22019-04-02 17:10:01 -0700162 outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_MUSIC),
François Gaffie1c878552018-11-22 16:53:21 +0100163 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
164 || outputs.isActiveLocally(
Eric Laurent83d17c22019-04-02 17:10:01 -0700165 toVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
François Gaffie1c878552018-11-22 16:53:21 +0100166 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800167 // routing is same as media without the "remote" device
168 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
169 availableOutputDevices,
170 availableInputDevices, outputs,
171 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
172 // if no media is playing on the device, check for mandatory use of "safe" speaker
173 // when media would have played on speaker, and the safe speaker path is available
174 if (!media_active_locally
175 && (device & AUDIO_DEVICE_OUT_SPEAKER)
176 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700177 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
178 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
179 }
François Gaffie2110e042015-03-24 08:41:51 +0100180 }
181 break;
182
183 case STRATEGY_DTMF:
184 if (!isInCall()) {
185 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800186 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800187 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
188 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100189 break;
190 }
191 // when in call, DTMF and PHONE strategies follow the same rules
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700192 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100193
194 case STRATEGY_PHONE:
195 // Force use of only devices on primary output if:
196 // - in call AND
197 // - cannot route from voice call RX OR
198 // - audio HAL version is < 3.0 and TX device is on the primary HW module
199 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
200 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
201 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
202 audio_devices_t availPrimaryInputDevices =
Mikhail Naganov93661932018-07-26 14:37:41 -0700203 availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800204
205 // TODO: getPrimaryOutput return only devices from first module in
206 // audio_policy_configuration.xml, hearing aid is not there, but it's
207 // a primary device
208 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100209 audio_devices_t availPrimaryOutputDevices =
François Gaffie11d30102018-11-02 16:09:09 +0100210 (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) &
Eric Laurent58a73fc2018-02-21 18:46:13 -0800211 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100212
213 if (((availableInputDevices.types() &
214 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
215 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700216 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100217 availableOutputDevicesType = availPrimaryOutputDevices;
218 }
219 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800220 // for phone strategy, we first consider the forced use and then the available devices by
221 // order of priority
François Gaffiedc7553f2018-11-02 10:39:57 +0100222 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100223 case AUDIO_POLICY_FORCE_BT_SCO:
224 if (!isInCall() || strategy != STRATEGY_DTMF) {
225 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
226 if (device) break;
227 }
228 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
229 if (device) break;
230 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
231 if (device) break;
232 // if SCO device is requested but no SCO device is available, fall back to default case
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700233 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100234
235 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800236 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
237 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100238 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
239 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100240 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800241 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100242 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
243 if (device) break;
244 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
245 if (device) break;
246 }
247 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
248 if (device) break;
249 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
250 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800251 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
252 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700253 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
254 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100255 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
256 if (device) break;
257 if (!isInCall()) {
258 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
259 if (device) break;
260 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
261 if (device) break;
262 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
263 if (device) break;
264 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
265 if (device) break;
266 }
267 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100268 break;
269
270 case AUDIO_POLICY_FORCE_SPEAKER:
271 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
272 // A2DP speaker when forcing to speaker output
273 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100274 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800275 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100276 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
277 if (device) break;
278 }
279 if (!isInCall()) {
280 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
281 if (device) break;
282 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
283 if (device) break;
284 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
285 if (device) break;
286 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
287 if (device) break;
288 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
289 if (device) break;
290 }
François Gaffie2110e042015-03-24 08:41:51 +0100291 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100292 break;
293 }
294 break;
295
296 case STRATEGY_SONIFICATION:
297
Eric Laurentdcd4ab12018-06-29 17:45:13 -0700298 // If incall, just select the STRATEGY_PHONE device
François Gaffie1c878552018-11-22 16:53:21 +0100299 if (isInCall() ||
Eric Laurent83d17c22019-04-02 17:10:01 -0700300 outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800301 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800302 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
303 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100304 break;
305 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700306 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100307
308 case STRATEGY_ENFORCED_AUDIBLE:
309 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
310 // except:
311 // - when in call where it doesn't default to STRATEGY_PHONE behavior
312 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
313
314 if ((strategy == STRATEGY_SONIFICATION) ||
François Gaffiedc7553f2018-11-02 10:39:57 +0100315 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
François Gaffie2110e042015-03-24 08:41:51 +0100316 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100317 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800318
319 // if SCO headset is connected and we are told to use it, play ringtone over
320 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800321 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800322 uint32_t device2 = AUDIO_DEVICE_NONE;
323 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
324 if (device2 == AUDIO_DEVICE_NONE) {
325 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
326 }
327 if (device2 == AUDIO_DEVICE_NONE) {
328 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
329 }
Jack He96117ae2018-02-12 20:52:53 -0800330 // Use ONLY Bluetooth SCO output when ringing in vibration mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100331 if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jack He96117ae2018-02-12 20:52:53 -0800332 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
François Gaffiedc7553f2018-11-02 10:39:57 +0100333 if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
Jack He96117ae2018-02-12 20:52:53 -0800334 == AUDIO_POLICY_FORCE_BT_SCO) {
335 if (device2 != AUDIO_DEVICE_NONE) {
336 device = device2;
337 break;
338 }
339 }
340 }
341 // Use both Bluetooth SCO and phone default output when ringing in normal mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100342 if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
juyuchen5fa0aed2018-05-16 10:58:37 +0800343 if ((strategy == STRATEGY_SONIFICATION) &&
344 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
345 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
346 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
347 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
348 }
Jack He96117ae2018-02-12 20:52:53 -0800349 if (device2 != AUDIO_DEVICE_NONE) {
350 device |= device2;
351 break;
352 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800353 }
354 }
François Gaffie2110e042015-03-24 08:41:51 +0100355 // The second device used for sonification is the same as the device used by media strategy
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700356 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100357
François Gaffie2110e042015-03-24 08:41:51 +0100358 case STRATEGY_ACCESSIBILITY:
359 if (strategy == STRATEGY_ACCESSIBILITY) {
360 // do not route accessibility prompts to a digital output currently configured with a
361 // compressed format as they would likely not be mixed and dropped.
362 for (size_t i = 0; i < outputs.size(); i++) {
363 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
François Gaffie11d30102018-11-02 16:09:09 +0100364 audio_devices_t devices = desc->devices().types() &
François Gaffie2110e042015-03-24 08:41:51 +0100365 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
366 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
367 devices != AUDIO_DEVICE_NONE) {
368 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
369 }
370 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800371 availableOutputDevices =
Mikhail Naganov708e0382018-05-30 09:53:04 -0700372 availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType);
Eric Laurent83d17c22019-04-02 17:10:01 -0700373 if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) ||
374 outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800375 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800376 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
377 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800378 }
379 if (isInCall()) {
380 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800381 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
382 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800383 }
François Gaffie2110e042015-03-24 08:41:51 +0100384 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800385 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700386 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100387
Eric Laurent28d09f02016-03-08 10:43:05 -0800388 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100389 case STRATEGY_REROUTING:
390 case STRATEGY_MEDIA: {
391 uint32_t device2 = AUDIO_DEVICE_NONE;
392 if (strategy != STRATEGY_SONIFICATION) {
393 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800394 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Aniket Kumar Lata4e464702019-01-10 23:38:46 -0800395 String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100396 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
397 }
398 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700399 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800400 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800401 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
402 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700403 break;
404 }
juyuchenebebb5f2019-01-11 14:41:04 +0800405 // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261).
406 if ((device2 == AUDIO_DEVICE_NONE) &&
407 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) {
Eric Laurent58a73fc2018-02-21 18:46:13 -0800408 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
409 }
François Gaffie2110e042015-03-24 08:41:51 +0100410 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100411 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800412 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100413 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
414 if (device2 == AUDIO_DEVICE_NONE) {
415 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
416 }
417 if (device2 == AUDIO_DEVICE_NONE) {
418 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
419 }
420 }
421 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100422 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
François Gaffie2110e042015-03-24 08:41:51 +0100423 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
424 }
425 if (device2 == AUDIO_DEVICE_NONE) {
426 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
427 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700428 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100429 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
430 }
431 if (device2 == AUDIO_DEVICE_NONE) {
432 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
433 }
434 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700435 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
436 }
437 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100438 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
439 }
440 if (device2 == AUDIO_DEVICE_NONE) {
441 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
442 }
443 if (device2 == AUDIO_DEVICE_NONE) {
444 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
445 }
446 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
447 // no sonification on aux digital (e.g. HDMI)
448 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
449 }
450 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100451 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
François Gaffie2110e042015-03-24 08:41:51 +0100452 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
453 }
454 if (device2 == AUDIO_DEVICE_NONE) {
455 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
456 }
457 int device3 = AUDIO_DEVICE_NONE;
458 if (strategy == STRATEGY_MEDIA) {
459 // ARC, SPDIF and AUX_LINE can co-exist with others.
460 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
461 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
462 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
463 }
464
465 device2 |= device3;
466 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
467 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
468 device |= device2;
469
470 // If hdmi system audio mode is on, remove speaker out of output list.
471 if ((strategy == STRATEGY_MEDIA) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100472 (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
François Gaffie2110e042015-03-24 08:41:51 +0100473 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
474 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
475 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700476
477 // for STRATEGY_SONIFICATION:
478 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
479 if ((strategy == STRATEGY_SONIFICATION) &&
480 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
481 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
482 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
483 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
484 }
François Gaffie2110e042015-03-24 08:41:51 +0100485 } break;
486
487 default:
488 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
489 break;
490 }
491
Eric Laurent5a2b6292016-04-14 18:05:57 -0700492 if (device == AUDIO_DEVICE_NONE) {
493 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
François Gaffiedc7553f2018-11-02 10:39:57 +0100494 device = getApmObserver()->getDefaultOutputDevice()->type();
Eric Laurent5a2b6292016-04-14 18:05:57 -0700495 ALOGE_IF(device == AUDIO_DEVICE_NONE,
496 "getDeviceForStrategy() no default device defined");
497 }
François Gaffie2110e042015-03-24 08:41:51 +0100498 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
499 return device;
500}
501
502
503audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
504{
Eric Laurentaf377772019-03-29 14:50:21 -0700505 const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
506 const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiedc7553f2018-11-02 10:39:57 +0100507 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100508 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
Eric Laurent5ee8d122019-04-19 15:41:52 -0700509 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
510 audio_devices_t availablePrimaryDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
511 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100512 uint32_t device = AUDIO_DEVICE_NONE;
513
Eric Laurentdc95a252018-04-12 12:46:56 -0700514 // when a call is active, force device selection to match source VOICE_COMMUNICATION
515 // for most other input sources to avoid rerouting call TX audio
516 if (isInCall()) {
517 switch (inputSource) {
518 case AUDIO_SOURCE_DEFAULT:
519 case AUDIO_SOURCE_MIC:
520 case AUDIO_SOURCE_VOICE_RECOGNITION:
521 case AUDIO_SOURCE_UNPROCESSED:
522 case AUDIO_SOURCE_HOTWORD:
523 case AUDIO_SOURCE_CAMCORDER:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800524 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700525 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
526 break;
527 default:
528 break;
529 }
530 }
531
François Gaffie2110e042015-03-24 08:41:51 +0100532 switch (inputSource) {
François Gaffie2110e042015-03-24 08:41:51 +0100533 case AUDIO_SOURCE_DEFAULT:
534 case AUDIO_SOURCE_MIC:
535 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
536 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100537 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100538 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
539 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
540 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
541 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700542 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
543 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100544 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
545 device = AUDIO_DEVICE_IN_USB_DEVICE;
546 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
547 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
548 }
549 break;
550
551 case AUDIO_SOURCE_VOICE_COMMUNICATION:
552 // Allow only use of devices on primary input if in call and HAL does not support routing
553 // to voice call path.
554 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
555 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
Eric Laurent5ee8d122019-04-19 15:41:52 -0700556 availableDeviceTypes = availablePrimaryDeviceTypes;
François Gaffie2110e042015-03-24 08:41:51 +0100557 }
558
François Gaffiedc7553f2018-11-02 10:39:57 +0100559 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100560 case AUDIO_POLICY_FORCE_BT_SCO:
561 // if SCO device is requested but no SCO device is available, fall back to default case
562 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
563 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
564 break;
565 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700566 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100567
568 default: // FORCE_NONE
569 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
570 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700571 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
572 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100573 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
574 device = AUDIO_DEVICE_IN_USB_DEVICE;
575 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
576 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
577 }
578 break;
579
580 case AUDIO_POLICY_FORCE_SPEAKER:
581 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
582 device = AUDIO_DEVICE_IN_BACK_MIC;
583 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
584 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
585 }
586 break;
587 }
588 break;
589
590 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800591 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100592 case AUDIO_SOURCE_HOTWORD:
Eric Laurent5ee8d122019-04-19 15:41:52 -0700593 if (inputSource == AUDIO_SOURCE_HOTWORD) {
594 availableDeviceTypes = availablePrimaryDeviceTypes;
595 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100596 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100597 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
598 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
599 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
600 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700601 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
602 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100603 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
604 device = AUDIO_DEVICE_IN_USB_DEVICE;
605 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
606 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
607 }
608 break;
609 case AUDIO_SOURCE_CAMCORDER:
610 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
611 device = AUDIO_DEVICE_IN_BACK_MIC;
612 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
613 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900614 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
615 // This is specifically for a device without built-in mic
616 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100617 }
618 break;
619 case AUDIO_SOURCE_VOICE_DOWNLINK:
620 case AUDIO_SOURCE_VOICE_CALL:
Eric Laurent5ee8d122019-04-19 15:41:52 -0700621 case AUDIO_SOURCE_VOICE_UPLINK:
François Gaffie2110e042015-03-24 08:41:51 +0100622 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
623 device = AUDIO_DEVICE_IN_VOICE_CALL;
624 }
625 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800626 case AUDIO_SOURCE_VOICE_PERFORMANCE:
627 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
628 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
629 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
630 device = AUDIO_DEVICE_IN_USB_HEADSET;
631 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
632 device = AUDIO_DEVICE_IN_USB_DEVICE;
633 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
634 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
635 }
636 break;
François Gaffie2110e042015-03-24 08:41:51 +0100637 case AUDIO_SOURCE_REMOTE_SUBMIX:
638 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
639 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
640 }
641 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800642 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100643 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
644 device = AUDIO_DEVICE_IN_FM_TUNER;
645 }
646 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800647 case AUDIO_SOURCE_ECHO_REFERENCE:
648 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
649 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
650 }
651 break;
François Gaffie2110e042015-03-24 08:41:51 +0100652 default:
653 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
654 break;
655 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700656 if (device == AUDIO_DEVICE_NONE) {
657 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
658 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
659 device = AUDIO_DEVICE_IN_STUB;
660 }
661 ALOGE_IF(device == AUDIO_DEVICE_NONE,
662 "getDeviceForInputSource() no default device defined");
663 }
François Gaffie2110e042015-03-24 08:41:51 +0100664 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
665 return device;
666}
667
François Gaffiedc7553f2018-11-02 10:39:57 +0100668void Engine::updateDeviceSelectionCache()
669{
670 for (const auto &iter : getProductStrategies()) {
671 const auto &strategy = iter.second;
672 auto devices = getDevicesForProductStrategy(strategy->getId());
673 mDevicesForStrategies[strategy->getId()] = devices;
674 strategy->setDeviceTypes(devices.types());
675 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
676 }
677}
678
679DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
680{
681 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
682 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
683 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
684
685 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
686 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
687 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
688 availableOutputDevices,
689 availableInputDevices, outputs,
690 (uint32_t)AUDIO_DEVICE_NONE);
691 return availableOutputDevices.getDevicesFromTypeMask(devices);
692}
693
694DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
695 const sp<DeviceDescriptor> &preferredDevice,
696 bool fromCache) const
697{
698 // First check for explict routing device
699 if (preferredDevice != nullptr) {
700 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
701 return DeviceVector(preferredDevice);
702 }
François Gaffiec005e562018-11-06 15:04:49 +0100703 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
Eric Laurentaf377772019-03-29 14:50:21 -0700704 const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100705 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100706 //
707 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
708 // be by APM?
709 //
François Gaffiec005e562018-11-06 15:04:49 +0100710 // Honor explicit routing requests only if all active clients have a preferred route in which
711 // case the last active client route is used
712 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
713 if (device != nullptr) {
714 return DeviceVector(device);
715 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100716
717 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
718}
719
720DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
721{
722 auto attributes = getAttributesForStreamType(stream);
723 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
724}
725
726sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
Mikhail Naganovbfac5832019-03-05 16:55:28 -0800727 sp<AudioPolicyMix> *mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100728{
François Gaffiec005e562018-11-06 15:04:49 +0100729 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
Eric Laurentaf377772019-03-29 14:50:21 -0700730 const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100731 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100732 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100733
François Gaffiedc7553f2018-11-02 10:39:57 +0100734 //
François Gaffiec005e562018-11-06 15:04:49 +0100735 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
736 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100737 //
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 =
741 findPreferredDevice(inputs, attr.source, availableInputDevices);
742 if (device != nullptr) {
743 return device;
744 }
745
746 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
747 if (device != nullptr) {
748 return device;
749 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100750 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
751
752 if (audio_is_remote_submix_device(deviceType)) {
753 address = "0";
754 std::size_t pos;
755 std::string tags { attr.tags };
756 if ((pos = tags.find("addr=")) != std::string::npos) {
757 address = tags.substr(pos + std::strlen("addr="));
758 }
759 }
760 return availableInputDevices.getDevice(deviceType,
761 String8(address.c_str()),
762 AUDIO_FORMAT_DEFAULT);
763}
764
François Gaffie2110e042015-03-24 08:41:51 +0100765} // namespace audio_policy
766} // namespace android
767
768