blob: fd6a013a766a9b11fedd20319a554b46c855764b [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:
François Gaffie1c878552018-11-22 16:53:21 +0100156 if (isInCall() || outputs.isActiveLocally(streamToVolumeSource(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 =
François Gaffie1c878552018-11-22 16:53:21 +0100162 outputs.isActiveLocally(streamToVolumeSource(AUDIO_STREAM_MUSIC),
163 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
164 || outputs.isActiveLocally(
165 streamToVolumeSource(AUDIO_STREAM_ACCESSIBILITY),
166 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() ||
300 outputs.isActiveLocally(streamToVolumeSource(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);
François Gaffie1c878552018-11-22 16:53:21 +0100373 if (outputs.isActive(streamToVolumeSource(AUDIO_STREAM_RING)) ||
374 outputs.isActive(streamToVolumeSource(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 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800405 if (device2 == AUDIO_DEVICE_NONE) {
406 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
407 }
François Gaffie2110e042015-03-24 08:41:51 +0100408 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100409 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800410 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100411 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
412 if (device2 == AUDIO_DEVICE_NONE) {
413 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
414 }
415 if (device2 == AUDIO_DEVICE_NONE) {
416 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
417 }
418 }
419 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100420 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
François Gaffie2110e042015-03-24 08:41:51 +0100421 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
422 }
423 if (device2 == AUDIO_DEVICE_NONE) {
424 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
425 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700426 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100427 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
428 }
429 if (device2 == AUDIO_DEVICE_NONE) {
430 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
431 }
432 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700433 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
434 }
435 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100436 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
437 }
438 if (device2 == AUDIO_DEVICE_NONE) {
439 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
440 }
441 if (device2 == AUDIO_DEVICE_NONE) {
442 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
443 }
444 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
445 // no sonification on aux digital (e.g. HDMI)
446 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
447 }
448 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100449 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
François Gaffie2110e042015-03-24 08:41:51 +0100450 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
451 }
452 if (device2 == AUDIO_DEVICE_NONE) {
453 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
454 }
455 int device3 = AUDIO_DEVICE_NONE;
456 if (strategy == STRATEGY_MEDIA) {
457 // ARC, SPDIF and AUX_LINE can co-exist with others.
458 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
459 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
460 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
461 }
462
463 device2 |= device3;
464 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
465 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
466 device |= device2;
467
468 // If hdmi system audio mode is on, remove speaker out of output list.
469 if ((strategy == STRATEGY_MEDIA) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100470 (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
François Gaffie2110e042015-03-24 08:41:51 +0100471 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
472 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
473 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700474
475 // for STRATEGY_SONIFICATION:
476 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
477 if ((strategy == STRATEGY_SONIFICATION) &&
478 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
479 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
480 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
481 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
482 }
François Gaffie2110e042015-03-24 08:41:51 +0100483 } break;
484
485 default:
486 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
487 break;
488 }
489
Eric Laurent5a2b6292016-04-14 18:05:57 -0700490 if (device == AUDIO_DEVICE_NONE) {
491 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
François Gaffiedc7553f2018-11-02 10:39:57 +0100492 device = getApmObserver()->getDefaultOutputDevice()->type();
Eric Laurent5a2b6292016-04-14 18:05:57 -0700493 ALOGE_IF(device == AUDIO_DEVICE_NONE,
494 "getDeviceForStrategy() no default device defined");
495 }
François Gaffie2110e042015-03-24 08:41:51 +0100496 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
497 return device;
498}
499
500
501audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
502{
François Gaffiedc7553f2018-11-02 10:39:57 +0100503 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
504 const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
505 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100506 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
507
508 uint32_t device = AUDIO_DEVICE_NONE;
509
Eric Laurentdc95a252018-04-12 12:46:56 -0700510 // when a call is active, force device selection to match source VOICE_COMMUNICATION
511 // for most other input sources to avoid rerouting call TX audio
512 if (isInCall()) {
513 switch (inputSource) {
514 case AUDIO_SOURCE_DEFAULT:
515 case AUDIO_SOURCE_MIC:
516 case AUDIO_SOURCE_VOICE_RECOGNITION:
517 case AUDIO_SOURCE_UNPROCESSED:
518 case AUDIO_SOURCE_HOTWORD:
519 case AUDIO_SOURCE_CAMCORDER:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800520 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700521 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
522 break;
523 default:
524 break;
525 }
526 }
527
François Gaffie2110e042015-03-24 08:41:51 +0100528 switch (inputSource) {
529 case AUDIO_SOURCE_VOICE_UPLINK:
530 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
531 device = AUDIO_DEVICE_IN_VOICE_CALL;
532 break;
533 }
534 break;
535
536 case AUDIO_SOURCE_DEFAULT:
537 case AUDIO_SOURCE_MIC:
538 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
539 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100540 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100541 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
542 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
543 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
544 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700545 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
546 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100547 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
548 device = AUDIO_DEVICE_IN_USB_DEVICE;
549 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
550 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
551 }
552 break;
553
554 case AUDIO_SOURCE_VOICE_COMMUNICATION:
555 // Allow only use of devices on primary input if in call and HAL does not support routing
556 // to voice call path.
557 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
558 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
559 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
Mikhail Naganov93661932018-07-26 14:37:41 -0700560 availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
561 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100562 }
563
François Gaffiedc7553f2018-11-02 10:39:57 +0100564 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100565 case AUDIO_POLICY_FORCE_BT_SCO:
566 // if SCO device is requested but no SCO device is available, fall back to default case
567 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
568 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
569 break;
570 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700571 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100572
573 default: // FORCE_NONE
574 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
575 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700576 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
577 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100578 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
579 device = AUDIO_DEVICE_IN_USB_DEVICE;
580 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
581 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
582 }
583 break;
584
585 case AUDIO_POLICY_FORCE_SPEAKER:
586 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
587 device = AUDIO_DEVICE_IN_BACK_MIC;
588 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
589 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
590 }
591 break;
592 }
593 break;
594
595 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800596 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100597 case AUDIO_SOURCE_HOTWORD:
François Gaffiedc7553f2018-11-02 10:39:57 +0100598 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100599 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
600 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
601 } else 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 case AUDIO_SOURCE_CAMCORDER:
612 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
613 device = AUDIO_DEVICE_IN_BACK_MIC;
614 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
615 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900616 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
617 // This is specifically for a device without built-in mic
618 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100619 }
620 break;
621 case AUDIO_SOURCE_VOICE_DOWNLINK:
622 case AUDIO_SOURCE_VOICE_CALL:
623 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
624 device = AUDIO_DEVICE_IN_VOICE_CALL;
625 }
626 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800627 case AUDIO_SOURCE_VOICE_PERFORMANCE:
628 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
629 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
630 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
631 device = AUDIO_DEVICE_IN_USB_HEADSET;
632 } 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;
François Gaffie2110e042015-03-24 08:41:51 +0100638 case AUDIO_SOURCE_REMOTE_SUBMIX:
639 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
640 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
641 }
642 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800643 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100644 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
645 device = AUDIO_DEVICE_IN_FM_TUNER;
646 }
647 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800648 case AUDIO_SOURCE_ECHO_REFERENCE:
649 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
650 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
651 }
652 break;
François Gaffie2110e042015-03-24 08:41:51 +0100653 default:
654 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
655 break;
656 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700657 if (device == AUDIO_DEVICE_NONE) {
658 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
659 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
660 device = AUDIO_DEVICE_IN_STUB;
661 }
662 ALOGE_IF(device == AUDIO_DEVICE_NONE,
663 "getDeviceForInputSource() no default device defined");
664 }
François Gaffie2110e042015-03-24 08:41:51 +0100665 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
666 return device;
667}
668
François Gaffiedc7553f2018-11-02 10:39:57 +0100669void Engine::updateDeviceSelectionCache()
670{
671 for (const auto &iter : getProductStrategies()) {
672 const auto &strategy = iter.second;
673 auto devices = getDevicesForProductStrategy(strategy->getId());
674 mDevicesForStrategies[strategy->getId()] = devices;
675 strategy->setDeviceTypes(devices.types());
676 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
677 }
678}
679
680DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
681{
682 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
683 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
684 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
685
686 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
687 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
688 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
689 availableOutputDevices,
690 availableInputDevices, outputs,
691 (uint32_t)AUDIO_DEVICE_NONE);
692 return availableOutputDevices.getDevicesFromTypeMask(devices);
693}
694
695DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
696 const sp<DeviceDescriptor> &preferredDevice,
697 bool fromCache) const
698{
699 // First check for explict routing device
700 if (preferredDevice != nullptr) {
701 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
702 return DeviceVector(preferredDevice);
703 }
François Gaffiec005e562018-11-06 15:04:49 +0100704 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
705 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
706 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100707 //
708 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
709 // be by APM?
710 //
François Gaffiec005e562018-11-06 15:04:49 +0100711 // Honor explicit routing requests only if all active clients have a preferred route in which
712 // case the last active client route is used
713 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
714 if (device != nullptr) {
715 return DeviceVector(device);
716 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100717
718 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
719}
720
721DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
722{
723 auto attributes = getAttributesForStreamType(stream);
724 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
725}
726
727sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
François Gaffiec005e562018-11-06 15:04:49 +0100728 AudioMix **mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100729{
François Gaffiec005e562018-11-06 15:04:49 +0100730 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
François Gaffiedc7553f2018-11-02 10:39:57 +0100731 const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100732 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100733 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100734
François Gaffiedc7553f2018-11-02 10:39:57 +0100735 //
François Gaffiec005e562018-11-06 15:04:49 +0100736 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
737 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100738 //
François Gaffiec005e562018-11-06 15:04:49 +0100739 // Honor explicit routing requests only if all active clients have a preferred route in which
740 // case the last active client route is used
741 sp<DeviceDescriptor> device =
742 findPreferredDevice(inputs, attr.source, availableInputDevices);
743 if (device != nullptr) {
744 return device;
745 }
746
747 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
748 if (device != nullptr) {
749 return device;
750 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100751 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
752
753 if (audio_is_remote_submix_device(deviceType)) {
754 address = "0";
755 std::size_t pos;
756 std::string tags { attr.tags };
757 if ((pos = tags.find("addr=")) != std::string::npos) {
758 address = tags.substr(pos + std::strlen("addr="));
759 }
760 }
761 return availableInputDevices.getDevice(deviceType,
762 String8(address.c_str()),
763 AUDIO_FORMAT_DEFAULT);
764}
765
François Gaffie2110e042015-03-24 08:41:51 +0100766template <>
767AudioPolicyManagerInterface *Engine::queryInterface()
768{
François Gaffiedc7553f2018-11-02 10:39:57 +0100769 return this;
François Gaffie2110e042015-03-24 08:41:51 +0100770}
771
772} // namespace audio_policy
773} // namespace android
774
775