blob: 23c020d7961b66062c8c1b75ed90502cf85f65a2 [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"
François Gaffie2110e042015-03-24 08:41:51 +010028#include <AudioPolicyManagerObserver.h>
29#include <AudioPort.h>
30#include <IOProfile.h>
31#include <policy.h>
32#include <utils/String8.h>
33#include <utils/Log.h>
34
35namespace android
36{
37namespace audio_policy
38{
39
40Engine::Engine()
41 : mManagerInterface(this),
42 mPhoneState(AUDIO_MODE_NORMAL),
43 mApmObserver(NULL)
44{
45 for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
46 mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
47 }
48}
49
50Engine::~Engine()
51{
52}
53
54void Engine::setObserver(AudioPolicyManagerObserver *observer)
55{
56 ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
57 mApmObserver = observer;
58}
59
60status_t Engine::initCheck()
61{
62 return (mApmObserver != NULL) ? NO_ERROR : NO_INIT;
63}
64
François Gaffie2110e042015-03-24 08:41:51 +010065status_t Engine::setPhoneState(audio_mode_t state)
66{
67 ALOGV("setPhoneState() state %d", state);
68
69 if (state < 0 || state >= AUDIO_MODE_CNT) {
70 ALOGW("setPhoneState() invalid state %d", state);
71 return BAD_VALUE;
72 }
73
74 if (state == mPhoneState ) {
75 ALOGW("setPhoneState() setting same state %d", state);
76 return BAD_VALUE;
77 }
78
79 // store previous phone state for management of sonification strategy below
80 int oldState = mPhoneState;
81 mPhoneState = state;
François Gaffied1ab2bd2015-12-02 18:20:06 +010082
François Gaffie2110e042015-03-24 08:41:51 +010083 if (!is_state_in_call(oldState) && is_state_in_call(state)) {
84 ALOGV(" Entering call in setPhoneState()");
François Gaffied1ab2bd2015-12-02 18:20:06 +010085 mApmObserver->getVolumeCurves().switchVolumeCurve(AUDIO_STREAM_VOICE_CALL,
86 AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010087 } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
88 ALOGV(" Exiting call in setPhoneState()");
François Gaffied1ab2bd2015-12-02 18:20:06 +010089 mApmObserver->getVolumeCurves().restoreOriginVolumeCurve(AUDIO_STREAM_DTMF);
François Gaffie2110e042015-03-24 08:41:51 +010090 }
91 return NO_ERROR;
92}
93
94status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
95{
96 switch(usage) {
97 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
98 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
99 config != AUDIO_POLICY_FORCE_NONE) {
100 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
101 return BAD_VALUE;
102 }
103 mForceUse[usage] = config;
104 break;
105 case AUDIO_POLICY_FORCE_FOR_MEDIA:
106 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
107 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
108 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
109 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
110 config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
111 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
112 return BAD_VALUE;
113 }
114 mForceUse[usage] = config;
115 break;
116 case AUDIO_POLICY_FORCE_FOR_RECORD:
117 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
118 config != AUDIO_POLICY_FORCE_NONE) {
119 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
120 return BAD_VALUE;
121 }
122 mForceUse[usage] = config;
123 break;
124 case AUDIO_POLICY_FORCE_FOR_DOCK:
125 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
126 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
127 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
128 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
129 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
130 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
131 }
132 mForceUse[usage] = config;
133 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 }
139 mForceUse[usage] = config;
140 break;
141 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
142 if (config != AUDIO_POLICY_FORCE_NONE &&
143 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
Phil Burk09bc4612016-02-24 15:58:15 -0800144 ALOGW("setForceUse() invalid config %d for HDMI_SYSTEM_AUDIO", config);
145 }
146 mForceUse[usage] = config;
147 break;
148 case AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND:
149 if (config != AUDIO_POLICY_FORCE_NONE &&
150 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER &&
jiabin81772902018-04-02 17:52:27 -0700151 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS &&
152 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_MANUAL) {
Phil Burk09bc4612016-02-24 15:58:15 -0800153 ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
154 return BAD_VALUE;
François Gaffie2110e042015-03-24 08:41:51 +0100155 }
156 mForceUse[usage] = config;
157 break;
Jack He96117ae2018-02-12 20:52:53 -0800158 case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
159 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
160 ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
161 return BAD_VALUE;
162 }
163 mForceUse[usage] = config;
164 break;
François Gaffie2110e042015-03-24 08:41:51 +0100165 default:
166 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800167 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100168 }
169 return NO_ERROR;
170}
171
172routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
173{
174 // stream to strategy mapping
175 switch (stream) {
176 case AUDIO_STREAM_VOICE_CALL:
177 case AUDIO_STREAM_BLUETOOTH_SCO:
178 return STRATEGY_PHONE;
179 case AUDIO_STREAM_RING:
180 case AUDIO_STREAM_ALARM:
181 return STRATEGY_SONIFICATION;
182 case AUDIO_STREAM_NOTIFICATION:
183 return STRATEGY_SONIFICATION_RESPECTFUL;
184 case AUDIO_STREAM_DTMF:
185 return STRATEGY_DTMF;
186 default:
187 ALOGE("unknown stream type %d", stream);
188 case AUDIO_STREAM_SYSTEM:
189 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
190 // while key clicks are played produces a poor result
191 case AUDIO_STREAM_MUSIC:
192 return STRATEGY_MEDIA;
193 case AUDIO_STREAM_ENFORCED_AUDIBLE:
194 return STRATEGY_ENFORCED_AUDIBLE;
195 case AUDIO_STREAM_TTS:
196 return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
197 case AUDIO_STREAM_ACCESSIBILITY:
198 return STRATEGY_ACCESSIBILITY;
199 case AUDIO_STREAM_REROUTING:
200 return STRATEGY_REROUTING;
201 }
202}
203
204routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
205{
François Gaffie2110e042015-03-24 08:41:51 +0100206 // usage to strategy mapping
207 switch (usage) {
208 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
François Gaffie2110e042015-03-24 08:41:51 +0100209 return STRATEGY_ACCESSIBILITY;
210
211 case AUDIO_USAGE_MEDIA:
212 case AUDIO_USAGE_GAME:
Jean-Michel Trivi36867762016-12-29 12:03:28 -0800213 case AUDIO_USAGE_ASSISTANT:
François Gaffie2110e042015-03-24 08:41:51 +0100214 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
215 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
216 return STRATEGY_MEDIA;
217
218 case AUDIO_USAGE_VOICE_COMMUNICATION:
219 return STRATEGY_PHONE;
220
221 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
222 return STRATEGY_DTMF;
223
224 case AUDIO_USAGE_ALARM:
225 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
226 return STRATEGY_SONIFICATION;
227
228 case AUDIO_USAGE_NOTIFICATION:
229 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
230 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
231 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
232 case AUDIO_USAGE_NOTIFICATION_EVENT:
233 return STRATEGY_SONIFICATION_RESPECTFUL;
234
235 case AUDIO_USAGE_UNKNOWN:
236 default:
237 return STRATEGY_MEDIA;
238 }
239}
240
241audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
242{
Eric Laurent0f928fa2016-03-21 12:06:20 -0700243 DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
244 DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
François Gaffie2110e042015-03-24 08:41:51 +0100245
Eric Laurentc75307b2015-03-17 15:29:32 -0700246 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100247
Eric Laurent0f928fa2016-03-21 12:06:20 -0700248 return getDeviceForStrategyInt(strategy, availableOutputDevices,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800249 availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
Eric Laurent28d09f02016-03-08 10:43:05 -0800250}
251
252
Eric Laurent28d09f02016-03-08 10:43:05 -0800253audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800254 DeviceVector availableOutputDevices,
255 DeviceVector availableInputDevices,
256 const SwAudioOutputCollection &outputs,
257 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800258{
François Gaffie2110e042015-03-24 08:41:51 +0100259 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800260 uint32_t availableOutputDevicesType =
261 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100262
263 switch (strategy) {
264
265 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
266 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100267 break;
268
269 case STRATEGY_SONIFICATION_RESPECTFUL:
Eric Laurent7731b5a2018-04-06 15:47:22 -0700270 if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800271 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800272 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
273 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100274 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800275 bool media_active_locally =
276 outputs.isStreamActiveLocally(
277 AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
278 || outputs.isStreamActiveLocally(
279 AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
280 // routing is same as media without the "remote" device
281 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
282 availableOutputDevices,
283 availableInputDevices, outputs,
284 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
285 // if no media is playing on the device, check for mandatory use of "safe" speaker
286 // when media would have played on speaker, and the safe speaker path is available
287 if (!media_active_locally
288 && (device & AUDIO_DEVICE_OUT_SPEAKER)
289 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700290 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
291 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
292 }
François Gaffie2110e042015-03-24 08:41:51 +0100293 }
294 break;
295
296 case STRATEGY_DTMF:
297 if (!isInCall()) {
298 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800299 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800300 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
301 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100302 break;
303 }
304 // when in call, DTMF and PHONE strategies follow the same rules
305 // FALL THROUGH
306
307 case STRATEGY_PHONE:
308 // Force use of only devices on primary output if:
309 // - in call AND
310 // - cannot route from voice call RX OR
311 // - audio HAL version is < 3.0 and TX device is on the primary HW module
312 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
313 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
314 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
315 audio_devices_t availPrimaryInputDevices =
316 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800317
318 // TODO: getPrimaryOutput return only devices from first module in
319 // audio_policy_configuration.xml, hearing aid is not there, but it's
320 // a primary device
321 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100322 audio_devices_t availPrimaryOutputDevices =
Eric Laurent58a73fc2018-02-21 18:46:13 -0800323 (primaryOutput->supportedDevices() | AUDIO_DEVICE_OUT_HEARING_AID) &
324 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100325
326 if (((availableInputDevices.types() &
327 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
328 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700329 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100330 availableOutputDevicesType = availPrimaryOutputDevices;
331 }
332 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800333 // for phone strategy, we first consider the forced use and then the available devices by
334 // order of priority
François Gaffie2110e042015-03-24 08:41:51 +0100335 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
336 case AUDIO_POLICY_FORCE_BT_SCO:
337 if (!isInCall() || strategy != STRATEGY_DTMF) {
338 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
339 if (device) break;
340 }
341 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
342 if (device) break;
343 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
344 if (device) break;
345 // if SCO device is requested but no SCO device is available, fall back to default case
346 // FALL THROUGH
347
348 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800349 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
350 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100351 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
352 if (!isInCall() &&
353 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800354 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100355 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
356 if (device) break;
357 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
358 if (device) break;
359 }
360 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
361 if (device) break;
362 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
363 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800364 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
365 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700366 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
367 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100368 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
369 if (device) break;
370 if (!isInCall()) {
371 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
372 if (device) break;
373 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
374 if (device) break;
375 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
376 if (device) break;
377 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
378 if (device) break;
379 }
380 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100381 break;
382
383 case AUDIO_POLICY_FORCE_SPEAKER:
384 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
385 // A2DP speaker when forcing to speaker output
386 if (!isInCall() &&
387 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800388 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100389 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
390 if (device) break;
391 }
392 if (!isInCall()) {
393 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
394 if (device) break;
395 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
396 if (device) break;
397 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
398 if (device) break;
399 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
400 if (device) break;
401 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
402 if (device) break;
403 }
François Gaffie2110e042015-03-24 08:41:51 +0100404 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100405 break;
406 }
407 break;
408
409 case STRATEGY_SONIFICATION:
410
411 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
412 // handleIncallSonification().
Eric Laurent7731b5a2018-04-06 15:47:22 -0700413 if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800414 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800415 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
416 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100417 break;
418 }
419 // FALL THROUGH
420
421 case STRATEGY_ENFORCED_AUDIBLE:
422 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
423 // except:
424 // - when in call where it doesn't default to STRATEGY_PHONE behavior
425 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
426
427 if ((strategy == STRATEGY_SONIFICATION) ||
428 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
429 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100430 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800431
432 // if SCO headset is connected and we are told to use it, play ringtone over
433 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800434 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800435 uint32_t device2 = AUDIO_DEVICE_NONE;
436 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
437 if (device2 == AUDIO_DEVICE_NONE) {
438 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
439 }
440 if (device2 == AUDIO_DEVICE_NONE) {
441 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
442 }
Jack He96117ae2018-02-12 20:52:53 -0800443 // Use ONLY Bluetooth SCO output when ringing in vibration mode
444 if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
445 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
446 if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
447 == AUDIO_POLICY_FORCE_BT_SCO) {
448 if (device2 != AUDIO_DEVICE_NONE) {
449 device = device2;
450 break;
451 }
452 }
453 }
454 // Use both Bluetooth SCO and phone default output when ringing in normal mode
455 if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
456 if (device2 != AUDIO_DEVICE_NONE) {
457 device |= device2;
458 break;
459 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800460 }
461 }
François Gaffie2110e042015-03-24 08:41:51 +0100462 // The second device used for sonification is the same as the device used by media strategy
463 // FALL THROUGH
464
François Gaffie2110e042015-03-24 08:41:51 +0100465 case STRATEGY_ACCESSIBILITY:
466 if (strategy == STRATEGY_ACCESSIBILITY) {
467 // do not route accessibility prompts to a digital output currently configured with a
468 // compressed format as they would likely not be mixed and dropped.
469 for (size_t i = 0; i < outputs.size(); i++) {
470 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
471 audio_devices_t devices = desc->device() &
472 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
473 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
474 devices != AUDIO_DEVICE_NONE) {
475 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
476 }
477 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800478 availableOutputDevices =
479 availableOutputDevices.getDevicesFromType(availableOutputDevicesType);
480 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
481 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
482 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800483 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
484 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800485 }
486 if (isInCall()) {
487 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800488 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
489 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800490 }
François Gaffie2110e042015-03-24 08:41:51 +0100491 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800492 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
François Gaffie2110e042015-03-24 08:41:51 +0100493 // FALL THROUGH
494
Eric Laurent28d09f02016-03-08 10:43:05 -0800495 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100496 case STRATEGY_REROUTING:
497 case STRATEGY_MEDIA: {
498 uint32_t device2 = AUDIO_DEVICE_NONE;
499 if (strategy != STRATEGY_SONIFICATION) {
500 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800501 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
502 String8("0")) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100503 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
504 }
505 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700506 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800507 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800508 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
509 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700510 break;
511 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800512 if (device2 == AUDIO_DEVICE_NONE) {
513 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
514 }
François Gaffie2110e042015-03-24 08:41:51 +0100515 if ((device2 == AUDIO_DEVICE_NONE) &&
516 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800517 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100518 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
519 if (device2 == AUDIO_DEVICE_NONE) {
520 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
521 }
522 if (device2 == AUDIO_DEVICE_NONE) {
523 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
524 }
525 }
526 if ((device2 == AUDIO_DEVICE_NONE) &&
527 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
528 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
529 }
530 if (device2 == AUDIO_DEVICE_NONE) {
531 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
532 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700533 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100534 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
535 }
536 if (device2 == AUDIO_DEVICE_NONE) {
537 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
538 }
539 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700540 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
541 }
542 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100543 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
544 }
545 if (device2 == AUDIO_DEVICE_NONE) {
546 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
547 }
548 if (device2 == AUDIO_DEVICE_NONE) {
549 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
550 }
551 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
552 // no sonification on aux digital (e.g. HDMI)
553 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
554 }
555 if ((device2 == AUDIO_DEVICE_NONE) &&
556 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
557 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
558 }
559 if (device2 == AUDIO_DEVICE_NONE) {
560 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
561 }
562 int device3 = AUDIO_DEVICE_NONE;
563 if (strategy == STRATEGY_MEDIA) {
564 // ARC, SPDIF and AUX_LINE can co-exist with others.
565 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
566 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
567 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
568 }
569
570 device2 |= device3;
571 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
572 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
573 device |= device2;
574
575 // If hdmi system audio mode is on, remove speaker out of output list.
576 if ((strategy == STRATEGY_MEDIA) &&
577 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
578 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
579 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
580 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700581
582 // for STRATEGY_SONIFICATION:
583 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
584 if ((strategy == STRATEGY_SONIFICATION) &&
585 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
586 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
587 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
588 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
589 }
François Gaffie2110e042015-03-24 08:41:51 +0100590 } break;
591
592 default:
593 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
594 break;
595 }
596
Eric Laurent5a2b6292016-04-14 18:05:57 -0700597 if (device == AUDIO_DEVICE_NONE) {
598 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
599 device = mApmObserver->getDefaultOutputDevice()->type();
600 ALOGE_IF(device == AUDIO_DEVICE_NONE,
601 "getDeviceForStrategy() no default device defined");
602 }
François Gaffie2110e042015-03-24 08:41:51 +0100603 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
604 return device;
605}
606
607
608audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
609{
610 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
611 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
Eric Laurentc75307b2015-03-17 15:29:32 -0700612 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100613 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
614
615 uint32_t device = AUDIO_DEVICE_NONE;
616
Eric Laurentdc95a252018-04-12 12:46:56 -0700617 // when a call is active, force device selection to match source VOICE_COMMUNICATION
618 // for most other input sources to avoid rerouting call TX audio
619 if (isInCall()) {
620 switch (inputSource) {
621 case AUDIO_SOURCE_DEFAULT:
622 case AUDIO_SOURCE_MIC:
623 case AUDIO_SOURCE_VOICE_RECOGNITION:
624 case AUDIO_SOURCE_UNPROCESSED:
625 case AUDIO_SOURCE_HOTWORD:
626 case AUDIO_SOURCE_CAMCORDER:
627 inputSource = AUDIO_SOURCE_VOICE_COMMUNICATION;
628 break;
629 default:
630 break;
631 }
632 }
633
François Gaffie2110e042015-03-24 08:41:51 +0100634 switch (inputSource) {
635 case AUDIO_SOURCE_VOICE_UPLINK:
636 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
637 device = AUDIO_DEVICE_IN_VOICE_CALL;
638 break;
639 }
640 break;
641
642 case AUDIO_SOURCE_DEFAULT:
643 case AUDIO_SOURCE_MIC:
644 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
645 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
646 } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
647 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
648 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
649 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
650 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700651 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
652 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100653 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
654 device = AUDIO_DEVICE_IN_USB_DEVICE;
655 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
656 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
657 }
658 break;
659
660 case AUDIO_SOURCE_VOICE_COMMUNICATION:
661 // Allow only use of devices on primary input if in call and HAL does not support routing
662 // to voice call path.
663 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
664 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
665 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
666 availableDeviceTypes =
667 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
668 & ~AUDIO_DEVICE_BIT_IN;
669 }
670
671 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
672 case AUDIO_POLICY_FORCE_BT_SCO:
673 // if SCO device is requested but no SCO device is available, fall back to default case
674 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
675 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
676 break;
677 }
678 // FALL THROUGH
679
680 default: // FORCE_NONE
681 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
682 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700683 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
684 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100685 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
686 device = AUDIO_DEVICE_IN_USB_DEVICE;
687 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
688 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
689 }
690 break;
691
692 case AUDIO_POLICY_FORCE_SPEAKER:
693 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
694 device = AUDIO_DEVICE_IN_BACK_MIC;
695 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
696 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
697 }
698 break;
699 }
700 break;
701
702 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800703 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100704 case AUDIO_SOURCE_HOTWORD:
705 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
706 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
707 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
708 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
709 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700710 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
711 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100712 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
713 device = AUDIO_DEVICE_IN_USB_DEVICE;
714 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
715 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
716 }
717 break;
718 case AUDIO_SOURCE_CAMCORDER:
719 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
720 device = AUDIO_DEVICE_IN_BACK_MIC;
721 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
722 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
723 }
724 break;
725 case AUDIO_SOURCE_VOICE_DOWNLINK:
726 case AUDIO_SOURCE_VOICE_CALL:
727 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
728 device = AUDIO_DEVICE_IN_VOICE_CALL;
729 }
730 break;
731 case AUDIO_SOURCE_REMOTE_SUBMIX:
732 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
733 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
734 }
735 break;
736 case AUDIO_SOURCE_FM_TUNER:
737 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
738 device = AUDIO_DEVICE_IN_FM_TUNER;
739 }
740 break;
741 default:
742 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
743 break;
744 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700745 if (device == AUDIO_DEVICE_NONE) {
746 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
747 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
748 device = AUDIO_DEVICE_IN_STUB;
749 }
750 ALOGE_IF(device == AUDIO_DEVICE_NONE,
751 "getDeviceForInputSource() no default device defined");
752 }
François Gaffie2110e042015-03-24 08:41:51 +0100753 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
754 return device;
755}
756
757template <>
758AudioPolicyManagerInterface *Engine::queryInterface()
759{
760 return &mManagerInterface;
761}
762
763} // namespace audio_policy
764} // namespace android
765
766