blob: 4135f01f7cfe78b92504c531ac34c57affa0333c [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;
509
510 uint32_t device = AUDIO_DEVICE_NONE;
511
Eric Laurentdc95a252018-04-12 12:46:56 -0700512 // when a call is active, force device selection to match source VOICE_COMMUNICATION
513 // for most other input sources to avoid rerouting call TX audio
514 if (isInCall()) {
515 switch (inputSource) {
516 case AUDIO_SOURCE_DEFAULT:
517 case AUDIO_SOURCE_MIC:
518 case AUDIO_SOURCE_VOICE_RECOGNITION:
519 case AUDIO_SOURCE_UNPROCESSED:
520 case AUDIO_SOURCE_HOTWORD:
521 case AUDIO_SOURCE_CAMCORDER:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800522 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700523 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
524 break;
525 default:
526 break;
527 }
528 }
529
François Gaffie2110e042015-03-24 08:41:51 +0100530 switch (inputSource) {
531 case AUDIO_SOURCE_VOICE_UPLINK:
532 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
533 device = AUDIO_DEVICE_IN_VOICE_CALL;
534 break;
535 }
536 break;
537
538 case AUDIO_SOURCE_DEFAULT:
539 case AUDIO_SOURCE_MIC:
540 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
541 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100542 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100543 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
544 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
545 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
546 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700547 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
548 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100549 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
550 device = AUDIO_DEVICE_IN_USB_DEVICE;
551 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
552 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
553 }
554 break;
555
556 case AUDIO_SOURCE_VOICE_COMMUNICATION:
557 // Allow only use of devices on primary input if in call and HAL does not support routing
558 // to voice call path.
559 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
560 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
561 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
Mikhail Naganov93661932018-07-26 14:37:41 -0700562 availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
563 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100564 }
565
François Gaffiedc7553f2018-11-02 10:39:57 +0100566 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100567 case AUDIO_POLICY_FORCE_BT_SCO:
568 // if SCO device is requested but no SCO device is available, fall back to default case
569 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
570 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
571 break;
572 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700573 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100574
575 default: // FORCE_NONE
576 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
577 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700578 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
579 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100580 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
581 device = AUDIO_DEVICE_IN_USB_DEVICE;
582 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
583 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
584 }
585 break;
586
587 case AUDIO_POLICY_FORCE_SPEAKER:
588 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
589 device = AUDIO_DEVICE_IN_BACK_MIC;
590 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
591 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
592 }
593 break;
594 }
595 break;
596
597 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800598 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100599 case AUDIO_SOURCE_HOTWORD:
François Gaffiedc7553f2018-11-02 10:39:57 +0100600 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100601 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
602 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
603 } else 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 case AUDIO_SOURCE_CAMCORDER:
614 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
615 device = AUDIO_DEVICE_IN_BACK_MIC;
616 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
617 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900618 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
619 // This is specifically for a device without built-in mic
620 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100621 }
622 break;
623 case AUDIO_SOURCE_VOICE_DOWNLINK:
624 case AUDIO_SOURCE_VOICE_CALL:
625 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
626 device = AUDIO_DEVICE_IN_VOICE_CALL;
627 }
628 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800629 case AUDIO_SOURCE_VOICE_PERFORMANCE:
630 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
631 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
632 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
633 device = AUDIO_DEVICE_IN_USB_HEADSET;
634 } 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;
François Gaffie2110e042015-03-24 08:41:51 +0100640 case AUDIO_SOURCE_REMOTE_SUBMIX:
641 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
642 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
643 }
644 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800645 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100646 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
647 device = AUDIO_DEVICE_IN_FM_TUNER;
648 }
649 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800650 case AUDIO_SOURCE_ECHO_REFERENCE:
651 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
652 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
653 }
654 break;
François Gaffie2110e042015-03-24 08:41:51 +0100655 default:
656 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
657 break;
658 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700659 if (device == AUDIO_DEVICE_NONE) {
660 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
661 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
662 device = AUDIO_DEVICE_IN_STUB;
663 }
664 ALOGE_IF(device == AUDIO_DEVICE_NONE,
665 "getDeviceForInputSource() no default device defined");
666 }
François Gaffie2110e042015-03-24 08:41:51 +0100667 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
668 return device;
669}
670
François Gaffiedc7553f2018-11-02 10:39:57 +0100671void Engine::updateDeviceSelectionCache()
672{
673 for (const auto &iter : getProductStrategies()) {
674 const auto &strategy = iter.second;
675 auto devices = getDevicesForProductStrategy(strategy->getId());
676 mDevicesForStrategies[strategy->getId()] = devices;
677 strategy->setDeviceTypes(devices.types());
678 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
679 }
680}
681
682DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
683{
684 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
685 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
686 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
687
688 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
689 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
690 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
691 availableOutputDevices,
692 availableInputDevices, outputs,
693 (uint32_t)AUDIO_DEVICE_NONE);
694 return availableOutputDevices.getDevicesFromTypeMask(devices);
695}
696
697DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
698 const sp<DeviceDescriptor> &preferredDevice,
699 bool fromCache) const
700{
701 // First check for explict routing device
702 if (preferredDevice != nullptr) {
703 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
704 return DeviceVector(preferredDevice);
705 }
François Gaffiec005e562018-11-06 15:04:49 +0100706 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
Eric Laurentaf377772019-03-29 14:50:21 -0700707 const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100708 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100709 //
710 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
711 // be by APM?
712 //
François Gaffiec005e562018-11-06 15:04:49 +0100713 // Honor explicit routing requests only if all active clients have a preferred route in which
714 // case the last active client route is used
715 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
716 if (device != nullptr) {
717 return DeviceVector(device);
718 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100719
720 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
721}
722
723DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
724{
725 auto attributes = getAttributesForStreamType(stream);
726 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
727}
728
729sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
Mikhail Naganovbfac5832019-03-05 16:55:28 -0800730 sp<AudioPolicyMix> *mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100731{
François Gaffiec005e562018-11-06 15:04:49 +0100732 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
Eric Laurentaf377772019-03-29 14:50:21 -0700733 const auto availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100734 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100735 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100736
François Gaffiedc7553f2018-11-02 10:39:57 +0100737 //
François Gaffiec005e562018-11-06 15:04:49 +0100738 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
739 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100740 //
François Gaffiec005e562018-11-06 15:04:49 +0100741 // Honor explicit routing requests only if all active clients have a preferred route in which
742 // case the last active client route is used
743 sp<DeviceDescriptor> device =
744 findPreferredDevice(inputs, attr.source, availableInputDevices);
745 if (device != nullptr) {
746 return device;
747 }
748
749 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
750 if (device != nullptr) {
751 return device;
752 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100753 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
754
755 if (audio_is_remote_submix_device(deviceType)) {
756 address = "0";
757 std::size_t pos;
758 std::string tags { attr.tags };
759 if ((pos = tags.find("addr=")) != std::string::npos) {
760 address = tags.substr(pos + std::strlen("addr="));
761 }
762 }
763 return availableInputDevices.getDevice(deviceType,
764 String8(address.c_str()),
765 AUDIO_FORMAT_DEFAULT);
766}
767
François Gaffie2110e042015-03-24 08:41:51 +0100768template <>
769AudioPolicyManagerInterface *Engine::queryInterface()
770{
François Gaffiedc7553f2018-11-02 10:39:57 +0100771 return this;
François Gaffie2110e042015-03-24 08:41:51 +0100772}
773
774} // namespace audio_policy
775} // namespace android
776
777