blob: a449df6d6c7737c6102249608f1d230e855d59db [file] [log] [blame]
François Gaffie2110e042015-03-24 08:41:51 +01001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "APM::AudioPolicyEngine"
18//#define LOG_NDEBUG 0
19
20//#define VERY_VERBOSE_LOGGING
21#ifdef VERY_VERBOSE_LOGGING
22#define ALOGVV ALOGV
23#else
24#define ALOGVV(a...) do { } while(0)
25#endif
26
27#include "Engine.h"
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -070028#include <android-base/macros.h>
François Gaffie2110e042015-03-24 08:41:51 +010029#include <AudioPolicyManagerObserver.h>
30#include <AudioPort.h>
31#include <IOProfile.h>
François Gaffiec005e562018-11-06 15:04:49 +010032#include <AudioIODescriptorInterface.h>
François Gaffie2110e042015-03-24 08:41:51 +010033#include <policy.h>
34#include <utils/String8.h>
35#include <utils/Log.h>
36
37namespace android
38{
39namespace audio_policy
40{
41
François Gaffiedc7553f2018-11-02 10:39:57 +010042struct legacy_strategy_map { const char *name; legacy_strategy id; };
43static const std::vector<legacy_strategy_map> gLegacyStrategy = {
44 { "STRATEGY_NONE", STRATEGY_NONE },
45 { "STRATEGY_MEDIA", STRATEGY_MEDIA },
46 { "STRATEGY_PHONE", STRATEGY_PHONE },
47 { "STRATEGY_SONIFICATION", STRATEGY_SONIFICATION },
48 { "STRATEGY_SONIFICATION_RESPECTFUL", STRATEGY_SONIFICATION_RESPECTFUL },
49 { "STRATEGY_DTMF", STRATEGY_DTMF },
50 { "STRATEGY_ENFORCED_AUDIBLE", STRATEGY_ENFORCED_AUDIBLE },
51 { "STRATEGY_TRANSMITTED_THROUGH_SPEAKER", STRATEGY_TRANSMITTED_THROUGH_SPEAKER },
52 { "STRATEGY_ACCESSIBILITY", STRATEGY_ACCESSIBILITY },
53 { "STRATEGY_REROUTING", STRATEGY_REROUTING },
54 { "STRATEGY_PATCH", STRATEGY_REROUTING }, // boiler to manage stream patch volume
55};
56
François Gaffie2110e042015-03-24 08:41:51 +010057Engine::Engine()
François Gaffie2110e042015-03-24 08:41:51 +010058{
François Gaffiedc7553f2018-11-02 10:39:57 +010059 auto result = EngineBase::loadAudioPolicyEngineConfig();
60 ALOGE_IF(result.nbSkippedElement != 0,
61 "Policy Engine configuration is partially invalid, skipped %zu elements",
62 result.nbSkippedElement);
63
64 for (const auto &strategy : gLegacyStrategy) {
65 mLegacyStrategyMap[getProductStrategyByName(strategy.name)] = strategy.id;
François Gaffie2110e042015-03-24 08:41:51 +010066 }
67}
68
François Gaffie2110e042015-03-24 08:41:51 +010069status_t Engine::setPhoneState(audio_mode_t state)
70{
71 ALOGV("setPhoneState() state %d", state);
72
73 if (state < 0 || state >= AUDIO_MODE_CNT) {
74 ALOGW("setPhoneState() invalid state %d", state);
75 return BAD_VALUE;
76 }
77
François Gaffiedc7553f2018-11-02 10:39:57 +010078 if (state == getPhoneState()) {
François Gaffie2110e042015-03-24 08:41:51 +010079 ALOGW("setPhoneState() setting same state %d", state);
80 return BAD_VALUE;
81 }
82
83 // store previous phone state for management of sonification strategy below
François Gaffiedc7553f2018-11-02 10:39:57 +010084 int oldState = getPhoneState();
85 EngineBase::setPhoneState(state);
François Gaffied1ab2bd2015-12-02 18:20:06 +010086
François Gaffie2110e042015-03-24 08:41:51 +010087 if (!is_state_in_call(oldState) && is_state_in_call(state)) {
88 ALOGV(" Entering call in setPhoneState()");
François Gaffiedc7553f2018-11-02 10:39:57 +010089 getApmObserver()->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
François Gaffied1ab2bd2015-12-02 18:20:06 +010090 AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010091 } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
92 ALOGV(" Exiting call in setPhoneState()");
François Gaffiedc7553f2018-11-02 10:39:57 +010093 getApmObserver()->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010094 }
95 return NO_ERROR;
96}
97
98status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
99{
100 switch(usage) {
101 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
102 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
103 config != AUDIO_POLICY_FORCE_NONE) {
104 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
105 return BAD_VALUE;
106 }
François Gaffie2110e042015-03-24 08:41:51 +0100107 break;
108 case AUDIO_POLICY_FORCE_FOR_MEDIA:
109 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
110 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
111 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
112 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
113 config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
114 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
115 return BAD_VALUE;
116 }
François Gaffie2110e042015-03-24 08:41:51 +0100117 break;
118 case AUDIO_POLICY_FORCE_FOR_RECORD:
119 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
120 config != AUDIO_POLICY_FORCE_NONE) {
121 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
122 return BAD_VALUE;
123 }
François Gaffie2110e042015-03-24 08:41:51 +0100124 break;
125 case AUDIO_POLICY_FORCE_FOR_DOCK:
126 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
127 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
128 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
129 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
130 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
131 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
132 }
François Gaffie2110e042015-03-24 08:41:51 +0100133 break;
134 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
135 if (config != AUDIO_POLICY_FORCE_NONE &&
136 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
137 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
138 }
François Gaffie2110e042015-03-24 08:41:51 +0100139 break;
140 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
141 if (config != AUDIO_POLICY_FORCE_NONE &&
142 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
Phil Burk09bc4612016-02-24 15:58:15 -0800143 ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
144 }
Phil Burk09bc4612016-02-24 15:58:15 -0800145 break;
146 case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
147 if (config != AUDIO_POLICY_FORCE_NONE &&
148 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
jiabin81772902018-04-02 17:52:27 -0700149 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
150 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
Phil Burk09bc4612016-02-24 15:58:15 -0800151 ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
152 return BAD_VALUE;
François Gaffie2110e042015-03-24 08:41:51 +0100153 }
François Gaffie2110e042015-03-24 08:41:51 +0100154 break;
Jack He96117ae2018-02-12 20:52:53 -0800155 case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
156 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
157 ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
158 return BAD_VALUE;
159 }
Jack He96117ae2018-02-12 20:52:53 -0800160 break;
François Gaffie2110e042015-03-24 08:41:51 +0100161 default:
162 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800163 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100164 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100165 return EngineBase::setForceUse(usage, config);
François Gaffie2110e042015-03-24 08:41:51 +0100166}
167
168routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
169{
170 // stream to strategy mapping
171 switch (stream) {
172 case AUDIO_STREAM_VOICE_CALL:
173 case AUDIO_STREAM_BLUETOOTH_SCO:
François Gaffiedc7553f2018-11-02 10:39:57 +0100174 return android::STRATEGY_PHONE;
François Gaffie2110e042015-03-24 08:41:51 +0100175 case AUDIO_STREAM_RING:
176 case AUDIO_STREAM_ALARM:
François Gaffiedc7553f2018-11-02 10:39:57 +0100177 return android::STRATEGY_SONIFICATION;
François Gaffie2110e042015-03-24 08:41:51 +0100178 case AUDIO_STREAM_NOTIFICATION:
François Gaffiedc7553f2018-11-02 10:39:57 +0100179 return android::STRATEGY_SONIFICATION_RESPECTFUL;
François Gaffie2110e042015-03-24 08:41:51 +0100180 case AUDIO_STREAM_DTMF:
François Gaffiedc7553f2018-11-02 10:39:57 +0100181 return android::STRATEGY_DTMF;
François Gaffie2110e042015-03-24 08:41:51 +0100182 default:
183 ALOGE("unknown stream type %d", stream);
Andy Hung320fd852018-10-09 14:06:37 -0700184 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100185 case AUDIO_STREAM_SYSTEM:
186 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
187 // while key clicks are played produces a poor result
188 case AUDIO_STREAM_MUSIC:
François Gaffiedc7553f2018-11-02 10:39:57 +0100189 return android::STRATEGY_MEDIA;
François Gaffie2110e042015-03-24 08:41:51 +0100190 case AUDIO_STREAM_ENFORCED_AUDIBLE:
François Gaffiedc7553f2018-11-02 10:39:57 +0100191 return android::STRATEGY_ENFORCED_AUDIBLE;
François Gaffie2110e042015-03-24 08:41:51 +0100192 case AUDIO_STREAM_TTS:
François Gaffiedc7553f2018-11-02 10:39:57 +0100193 return android::STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100194 case AUDIO_STREAM_ACCESSIBILITY:
François Gaffiedc7553f2018-11-02 10:39:57 +0100195 return android::STRATEGY_ACCESSIBILITY;
François Gaffie2110e042015-03-24 08:41:51 +0100196 case AUDIO_STREAM_REROUTING:
François Gaffiedc7553f2018-11-02 10:39:57 +0100197 return android::STRATEGY_REROUTING;
François Gaffie2110e042015-03-24 08:41:51 +0100198 }
199}
200
201routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
202{
François Gaffie2110e042015-03-24 08:41:51 +0100203 // usage to strategy mapping
204 switch (usage) {
205 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
François Gaffiedc7553f2018-11-02 10:39:57 +0100206 return android::STRATEGY_ACCESSIBILITY;
François Gaffie2110e042015-03-24 08:41:51 +0100207
208 case AUDIO_USAGE_MEDIA:
209 case AUDIO_USAGE_GAME:
Jean-Michel Trivi36867762016-12-29 12:03:28 -0800210 case AUDIO_USAGE_ASSISTANT:
François Gaffie2110e042015-03-24 08:41:51 +0100211 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
212 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
François Gaffiedc7553f2018-11-02 10:39:57 +0100213 return android::STRATEGY_MEDIA;
François Gaffie2110e042015-03-24 08:41:51 +0100214
215 case AUDIO_USAGE_VOICE_COMMUNICATION:
François Gaffiedc7553f2018-11-02 10:39:57 +0100216 return android::STRATEGY_PHONE;
François Gaffie2110e042015-03-24 08:41:51 +0100217
218 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
François Gaffiedc7553f2018-11-02 10:39:57 +0100219 return android::STRATEGY_DTMF;
François Gaffie2110e042015-03-24 08:41:51 +0100220
221 case AUDIO_USAGE_ALARM:
222 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
François Gaffiedc7553f2018-11-02 10:39:57 +0100223 return android::STRATEGY_SONIFICATION;
François Gaffie2110e042015-03-24 08:41:51 +0100224
225 case AUDIO_USAGE_NOTIFICATION:
226 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
227 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
228 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
229 case AUDIO_USAGE_NOTIFICATION_EVENT:
François Gaffiedc7553f2018-11-02 10:39:57 +0100230 return android::STRATEGY_SONIFICATION_RESPECTFUL;
François Gaffie2110e042015-03-24 08:41:51 +0100231
232 case AUDIO_USAGE_UNKNOWN:
233 default:
François Gaffiedc7553f2018-11-02 10:39:57 +0100234 return android::STRATEGY_MEDIA;
François Gaffie2110e042015-03-24 08:41:51 +0100235 }
236}
237
238audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
239{
François Gaffiedc7553f2018-11-02 10:39:57 +0100240 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
241 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffie2110e042015-03-24 08:41:51 +0100242
François Gaffiedc7553f2018-11-02 10:39:57 +0100243 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100244
François Gaffiec005e562018-11-06 15:04:49 +0100245 return getDeviceForStrategyInt(static_cast<legacy_strategy>(strategy),
246 availableOutputDevices,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800247 availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
Eric Laurent28d09f02016-03-08 10:43:05 -0800248}
249
François Gaffiedc7553f2018-11-02 10:39:57 +0100250audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy,
251 DeviceVector availableOutputDevices,
252 DeviceVector availableInputDevices,
253 const SwAudioOutputCollection &outputs,
254 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800255{
François Gaffie2110e042015-03-24 08:41:51 +0100256 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800257 uint32_t availableOutputDevicesType =
258 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100259
260 switch (strategy) {
261
262 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
263 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100264 break;
265
266 case STRATEGY_SONIFICATION_RESPECTFUL:
Eric Laurent7731b5a2018-04-06 15:47:22 -0700267 if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800268 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800269 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
270 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100271 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800272 bool media_active_locally =
273 outputs.isStreamActiveLocally(
274 AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
275 || outputs.isStreamActiveLocally(
276 AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
277 // routing is same as media without the "remote" device
278 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
279 availableOutputDevices,
280 availableInputDevices, outputs,
281 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
282 // if no media is playing on the device, check for mandatory use of "safe" speaker
283 // when media would have played on speaker, and the safe speaker path is available
284 if (!media_active_locally
285 && (device & AUDIO_DEVICE_OUT_SPEAKER)
286 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700287 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
288 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
289 }
François Gaffie2110e042015-03-24 08:41:51 +0100290 }
291 break;
292
293 case STRATEGY_DTMF:
294 if (!isInCall()) {
295 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800296 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800297 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
298 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100299 break;
300 }
301 // when in call, DTMF and PHONE strategies follow the same rules
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700302 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100303
304 case STRATEGY_PHONE:
305 // Force use of only devices on primary output if:
306 // - in call AND
307 // - cannot route from voice call RX OR
308 // - audio HAL version is < 3.0 and TX device is on the primary HW module
309 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
310 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
311 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
312 audio_devices_t availPrimaryInputDevices =
Mikhail Naganov93661932018-07-26 14:37:41 -0700313 availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800314
315 // TODO: getPrimaryOutput return only devices from first module in
316 // audio_policy_configuration.xml, hearing aid is not there, but it's
317 // a primary device
318 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100319 audio_devices_t availPrimaryOutputDevices =
François Gaffie11d30102018-11-02 16:09:09 +0100320 (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) &
Eric Laurent58a73fc2018-02-21 18:46:13 -0800321 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100322
323 if (((availableInputDevices.types() &
324 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
325 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700326 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100327 availableOutputDevicesType = availPrimaryOutputDevices;
328 }
329 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800330 // for phone strategy, we first consider the forced use and then the available devices by
331 // order of priority
François Gaffiedc7553f2018-11-02 10:39:57 +0100332 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100333 case AUDIO_POLICY_FORCE_BT_SCO:
334 if (!isInCall() || strategy != STRATEGY_DTMF) {
335 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
336 if (device) break;
337 }
338 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
339 if (device) break;
340 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
341 if (device) break;
342 // if SCO device is requested but no SCO device is available, fall back to default case
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700343 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100344
345 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800346 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
347 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100348 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
349 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100350 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800351 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100352 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
353 if (device) break;
354 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
355 if (device) break;
356 }
357 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
358 if (device) break;
359 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
360 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800361 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
362 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700363 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
364 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100365 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
366 if (device) break;
367 if (!isInCall()) {
368 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
369 if (device) break;
370 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
371 if (device) break;
372 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
373 if (device) break;
374 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
375 if (device) break;
376 }
377 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100378 break;
379
380 case AUDIO_POLICY_FORCE_SPEAKER:
381 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
382 // A2DP speaker when forcing to speaker output
383 if (!isInCall() &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100384 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800385 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100386 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
387 if (device) break;
388 }
389 if (!isInCall()) {
390 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
391 if (device) break;
392 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
393 if (device) break;
394 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
395 if (device) break;
396 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
397 if (device) break;
398 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
399 if (device) break;
400 }
François Gaffie2110e042015-03-24 08:41:51 +0100401 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100402 break;
403 }
404 break;
405
406 case STRATEGY_SONIFICATION:
407
Eric Laurentdcd4ab12018-06-29 17:45:13 -0700408 // If incall, just select the STRATEGY_PHONE device
Eric Laurent7731b5a2018-04-06 15:47:22 -0700409 if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800410 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800411 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
412 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100413 break;
414 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700415 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100416
417 case STRATEGY_ENFORCED_AUDIBLE:
418 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
419 // except:
420 // - when in call where it doesn't default to STRATEGY_PHONE behavior
421 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
422
423 if ((strategy == STRATEGY_SONIFICATION) ||
François Gaffiedc7553f2018-11-02 10:39:57 +0100424 (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
François Gaffie2110e042015-03-24 08:41:51 +0100425 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100426 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800427
428 // if SCO headset is connected and we are told to use it, play ringtone over
429 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800430 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800431 uint32_t device2 = AUDIO_DEVICE_NONE;
432 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
433 if (device2 == AUDIO_DEVICE_NONE) {
434 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
435 }
436 if (device2 == AUDIO_DEVICE_NONE) {
437 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
438 }
Jack He96117ae2018-02-12 20:52:53 -0800439 // Use ONLY Bluetooth SCO output when ringing in vibration mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100440 if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jack He96117ae2018-02-12 20:52:53 -0800441 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
François Gaffiedc7553f2018-11-02 10:39:57 +0100442 if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING)
Jack He96117ae2018-02-12 20:52:53 -0800443 == AUDIO_POLICY_FORCE_BT_SCO) {
444 if (device2 != AUDIO_DEVICE_NONE) {
445 device = device2;
446 break;
447 }
448 }
449 }
450 // Use both Bluetooth SCO and phone default output when ringing in normal mode
François Gaffiedc7553f2018-11-02 10:39:57 +0100451 if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) {
juyuchen5fa0aed2018-05-16 10:58:37 +0800452 if ((strategy == STRATEGY_SONIFICATION) &&
453 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
454 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
455 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
456 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
457 }
Jack He96117ae2018-02-12 20:52:53 -0800458 if (device2 != AUDIO_DEVICE_NONE) {
459 device |= device2;
460 break;
461 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800462 }
463 }
François Gaffie2110e042015-03-24 08:41:51 +0100464 // The second device used for sonification is the same as the device used by media strategy
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700465 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100466
François Gaffie2110e042015-03-24 08:41:51 +0100467 case STRATEGY_ACCESSIBILITY:
468 if (strategy == STRATEGY_ACCESSIBILITY) {
469 // do not route accessibility prompts to a digital output currently configured with a
470 // compressed format as they would likely not be mixed and dropped.
471 for (size_t i = 0; i < outputs.size(); i++) {
472 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
François Gaffie11d30102018-11-02 16:09:09 +0100473 audio_devices_t devices = desc->devices().types() &
François Gaffie2110e042015-03-24 08:41:51 +0100474 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
475 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
476 devices != AUDIO_DEVICE_NONE) {
477 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
478 }
479 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800480 availableOutputDevices =
Mikhail Naganov708e0382018-05-30 09:53:04 -0700481 availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType);
Eric Laurent28d09f02016-03-08 10:43:05 -0800482 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
483 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
484 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800485 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
486 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800487 }
488 if (isInCall()) {
489 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800490 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
491 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800492 }
François Gaffie2110e042015-03-24 08:41:51 +0100493 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800494 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700495 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100496
Eric Laurent28d09f02016-03-08 10:43:05 -0800497 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100498 case STRATEGY_REROUTING:
499 case STRATEGY_MEDIA: {
500 uint32_t device2 = AUDIO_DEVICE_NONE;
501 if (strategy != STRATEGY_SONIFICATION) {
502 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800503 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Aniket Kumar Lata4e464702019-01-10 23:38:46 -0800504 String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100505 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
506 }
507 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700508 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800509 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800510 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
511 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700512 break;
513 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800514 if (device2 == AUDIO_DEVICE_NONE) {
515 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
516 }
François Gaffie2110e042015-03-24 08:41:51 +0100517 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100518 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800519 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100520 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
521 if (device2 == AUDIO_DEVICE_NONE) {
522 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
523 }
524 if (device2 == AUDIO_DEVICE_NONE) {
525 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
526 }
527 }
528 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100529 (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) {
François Gaffie2110e042015-03-24 08:41:51 +0100530 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
531 }
532 if (device2 == AUDIO_DEVICE_NONE) {
533 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
534 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700535 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100536 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
537 }
538 if (device2 == AUDIO_DEVICE_NONE) {
539 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
540 }
541 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700542 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
543 }
544 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100545 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
546 }
547 if (device2 == AUDIO_DEVICE_NONE) {
548 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
549 }
550 if (device2 == AUDIO_DEVICE_NONE) {
551 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
552 }
553 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
554 // no sonification on aux digital (e.g. HDMI)
555 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
556 }
557 if ((device2 == AUDIO_DEVICE_NONE) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100558 (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
François Gaffie2110e042015-03-24 08:41:51 +0100559 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
560 }
561 if (device2 == AUDIO_DEVICE_NONE) {
562 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
563 }
564 int device3 = AUDIO_DEVICE_NONE;
565 if (strategy == STRATEGY_MEDIA) {
566 // ARC, SPDIF and AUX_LINE can co-exist with others.
567 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
568 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
569 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
570 }
571
572 device2 |= device3;
573 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
574 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
575 device |= device2;
576
577 // If hdmi system audio mode is on, remove speaker out of output list.
578 if ((strategy == STRATEGY_MEDIA) &&
François Gaffiedc7553f2018-11-02 10:39:57 +0100579 (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) ==
François Gaffie2110e042015-03-24 08:41:51 +0100580 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
581 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
582 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700583
584 // for STRATEGY_SONIFICATION:
585 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
586 if ((strategy == STRATEGY_SONIFICATION) &&
587 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
588 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
589 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
590 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
591 }
François Gaffie2110e042015-03-24 08:41:51 +0100592 } break;
593
594 default:
595 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
596 break;
597 }
598
Eric Laurent5a2b6292016-04-14 18:05:57 -0700599 if (device == AUDIO_DEVICE_NONE) {
600 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
François Gaffiedc7553f2018-11-02 10:39:57 +0100601 device = getApmObserver()->getDefaultOutputDevice()->type();
Eric Laurent5a2b6292016-04-14 18:05:57 -0700602 ALOGE_IF(device == AUDIO_DEVICE_NONE,
603 "getDeviceForStrategy() no default device defined");
604 }
François Gaffie2110e042015-03-24 08:41:51 +0100605 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
606 return device;
607}
608
609
610audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
611{
François Gaffiedc7553f2018-11-02 10:39:57 +0100612 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
613 const DeviceVector &availableInputDevices = getApmObserver()->getAvailableInputDevices();
614 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100615 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
616
617 uint32_t device = AUDIO_DEVICE_NONE;
618
Eric Laurentdc95a252018-04-12 12:46:56 -0700619 // when a call is active, force device selection to match source VOICE_COMMUNICATION
620 // for most other input sources to avoid rerouting call TX audio
621 if (isInCall()) {
622 switch (inputSource) {
623 case AUDIO_SOURCE_DEFAULT:
624 case AUDIO_SOURCE_MIC:
625 case AUDIO_SOURCE_VOICE_RECOGNITION:
626 case AUDIO_SOURCE_UNPROCESSED:
627 case AUDIO_SOURCE_HOTWORD:
628 case AUDIO_SOURCE_CAMCORDER:
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800629 case AUDIO_SOURCE_VOICE_PERFORMANCE:
Eric Laurentdc95a252018-04-12 12:46:56 -0700630 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
631 break;
632 default:
633 break;
634 }
635 }
636
François Gaffie2110e042015-03-24 08:41:51 +0100637 switch (inputSource) {
638 case AUDIO_SOURCE_VOICE_UPLINK:
639 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
640 device = AUDIO_DEVICE_IN_VOICE_CALL;
641 break;
642 }
643 break;
644
645 case AUDIO_SOURCE_DEFAULT:
646 case AUDIO_SOURCE_MIC:
647 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
648 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
François Gaffiedc7553f2018-11-02 10:39:57 +0100649 } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) &&
François Gaffie2110e042015-03-24 08:41:51 +0100650 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
651 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
652 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
653 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700654 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
655 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100656 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
657 device = AUDIO_DEVICE_IN_USB_DEVICE;
658 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
659 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
660 }
661 break;
662
663 case AUDIO_SOURCE_VOICE_COMMUNICATION:
664 // Allow only use of devices on primary input if in call and HAL does not support routing
665 // to voice call path.
666 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
667 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
668 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
Mikhail Naganov93661932018-07-26 14:37:41 -0700669 availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
670 primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
François Gaffie2110e042015-03-24 08:41:51 +0100671 }
672
François Gaffiedc7553f2018-11-02 10:39:57 +0100673 switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
François Gaffie2110e042015-03-24 08:41:51 +0100674 case AUDIO_POLICY_FORCE_BT_SCO:
675 // if SCO device is requested but no SCO device is available, fall back to default case
676 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
677 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
678 break;
679 }
Chih-Hung Hsieh2b487032018-09-13 14:16:02 -0700680 FALLTHROUGH_INTENDED;
François Gaffie2110e042015-03-24 08:41:51 +0100681
682 default: // FORCE_NONE
683 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
684 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700685 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
686 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100687 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
688 device = AUDIO_DEVICE_IN_USB_DEVICE;
689 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
690 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
691 }
692 break;
693
694 case AUDIO_POLICY_FORCE_SPEAKER:
695 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
696 device = AUDIO_DEVICE_IN_BACK_MIC;
697 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
698 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
699 }
700 break;
701 }
702 break;
703
704 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800705 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100706 case AUDIO_SOURCE_HOTWORD:
François Gaffiedc7553f2018-11-02 10:39:57 +0100707 if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
François Gaffie2110e042015-03-24 08:41:51 +0100708 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
709 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
710 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
711 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700712 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
713 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100714 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
715 device = AUDIO_DEVICE_IN_USB_DEVICE;
716 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
717 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
718 }
719 break;
720 case AUDIO_SOURCE_CAMCORDER:
721 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
722 device = AUDIO_DEVICE_IN_BACK_MIC;
723 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
724 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Takeshi Oishi86ad3d12018-07-20 16:13:06 +0900725 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
726 // This is specifically for a device without built-in mic
727 device = AUDIO_DEVICE_IN_USB_DEVICE;
François Gaffie2110e042015-03-24 08:41:51 +0100728 }
729 break;
730 case AUDIO_SOURCE_VOICE_DOWNLINK:
731 case AUDIO_SOURCE_VOICE_CALL:
732 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
733 device = AUDIO_DEVICE_IN_VOICE_CALL;
734 }
735 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800736 case AUDIO_SOURCE_VOICE_PERFORMANCE:
737 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
738 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
739 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
740 device = AUDIO_DEVICE_IN_USB_HEADSET;
741 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
742 device = AUDIO_DEVICE_IN_USB_DEVICE;
743 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
744 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
745 }
746 break;
François Gaffie2110e042015-03-24 08:41:51 +0100747 case AUDIO_SOURCE_REMOTE_SUBMIX:
748 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
749 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
750 }
751 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800752 case AUDIO_SOURCE_FM_TUNER:
François Gaffie2110e042015-03-24 08:41:51 +0100753 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
754 device = AUDIO_DEVICE_IN_FM_TUNER;
755 }
756 break;
Eric Laurentae4b6ec2019-01-15 18:34:38 -0800757 case AUDIO_SOURCE_ECHO_REFERENCE:
758 if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) {
759 device = AUDIO_DEVICE_IN_ECHO_REFERENCE;
760 }
761 break;
François Gaffie2110e042015-03-24 08:41:51 +0100762 default:
763 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
764 break;
765 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700766 if (device == AUDIO_DEVICE_NONE) {
767 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
768 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
769 device = AUDIO_DEVICE_IN_STUB;
770 }
771 ALOGE_IF(device == AUDIO_DEVICE_NONE,
772 "getDeviceForInputSource() no default device defined");
773 }
François Gaffie2110e042015-03-24 08:41:51 +0100774 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
775 return device;
776}
777
François Gaffiedc7553f2018-11-02 10:39:57 +0100778void Engine::updateDeviceSelectionCache()
779{
780 for (const auto &iter : getProductStrategies()) {
781 const auto &strategy = iter.second;
782 auto devices = getDevicesForProductStrategy(strategy->getId());
783 mDevicesForStrategies[strategy->getId()] = devices;
784 strategy->setDeviceTypes(devices.types());
785 strategy->setDeviceAddress(devices.getFirstValidAddress().c_str());
786 }
787}
788
789DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) const
790{
791 DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
792 DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
793 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
794
795 auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ?
796 mLegacyStrategyMap.at(strategy) : STRATEGY_NONE;
797 audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy,
798 availableOutputDevices,
799 availableInputDevices, outputs,
800 (uint32_t)AUDIO_DEVICE_NONE);
801 return availableOutputDevices.getDevicesFromTypeMask(devices);
802}
803
804DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,
805 const sp<DeviceDescriptor> &preferredDevice,
806 bool fromCache) const
807{
808 // First check for explict routing device
809 if (preferredDevice != nullptr) {
810 ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
811 return DeviceVector(preferredDevice);
812 }
François Gaffiec005e562018-11-06 15:04:49 +0100813 product_strategy_t strategy = getProductStrategyForAttributes(attributes);
814 const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
815 const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100816 //
817 // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
818 // be by APM?
819 //
François Gaffiec005e562018-11-06 15:04:49 +0100820 // Honor explicit routing requests only if all active clients have a preferred route in which
821 // case the last active client route is used
822 sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
823 if (device != nullptr) {
824 return DeviceVector(device);
825 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100826
827 return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
828}
829
830DeviceVector Engine::getOutputDevicesForStream(audio_stream_type_t stream, bool fromCache) const
831{
832 auto attributes = getAttributesForStreamType(stream);
833 return getOutputDevicesForAttributes(attributes, nullptr, fromCache);
834}
835
836sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
François Gaffiec005e562018-11-06 15:04:49 +0100837 AudioMix **mix) const
François Gaffiedc7553f2018-11-02 10:39:57 +0100838{
François Gaffiec005e562018-11-06 15:04:49 +0100839 const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
François Gaffiedc7553f2018-11-02 10:39:57 +0100840 const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
François Gaffiec005e562018-11-06 15:04:49 +0100841 const auto &inputs = getApmObserver()->getInputs();
François Gaffiedc7553f2018-11-02 10:39:57 +0100842 std::string address;
François Gaffiec005e562018-11-06 15:04:49 +0100843
François Gaffiedc7553f2018-11-02 10:39:57 +0100844 //
François Gaffiec005e562018-11-06 15:04:49 +0100845 // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
846 // first as it used to be by APM?
François Gaffiedc7553f2018-11-02 10:39:57 +0100847 //
François Gaffiec005e562018-11-06 15:04:49 +0100848 // Honor explicit routing requests only if all active clients have a preferred route in which
849 // case the last active client route is used
850 sp<DeviceDescriptor> device =
851 findPreferredDevice(inputs, attr.source, availableInputDevices);
852 if (device != nullptr) {
853 return device;
854 }
855
856 device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
857 if (device != nullptr) {
858 return device;
859 }
François Gaffiedc7553f2018-11-02 10:39:57 +0100860 audio_devices_t deviceType = getDeviceForInputSource(attr.source);
861
862 if (audio_is_remote_submix_device(deviceType)) {
863 address = "0";
864 std::size_t pos;
865 std::string tags { attr.tags };
866 if ((pos = tags.find("addr=")) != std::string::npos) {
867 address = tags.substr(pos + std::strlen("addr="));
868 }
869 }
870 return availableInputDevices.getDevice(deviceType,
871 String8(address.c_str()),
872 AUDIO_FORMAT_DEFAULT);
873}
874
François Gaffie2110e042015-03-24 08:41:51 +0100875template <>
876AudioPolicyManagerInterface *Engine::queryInterface()
877{
François Gaffiedc7553f2018-11-02 10:39:57 +0100878 return this;
François Gaffie2110e042015-03-24 08:41:51 +0100879}
880
881} // namespace audio_policy
882} // namespace android
883
884