blob: 5ec04757ef66994c5c2a064af00e2981a713663c [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 &&
151 config != AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
152 ALOGW("setForceUse() invalid config %d for ENCODED_SURROUND", config);
153 return BAD_VALUE;
François Gaffie2110e042015-03-24 08:41:51 +0100154 }
155 mForceUse[usage] = config;
156 break;
157 default:
158 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800159 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100160 }
161 return NO_ERROR;
162}
163
164routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
165{
166 // stream to strategy mapping
167 switch (stream) {
168 case AUDIO_STREAM_VOICE_CALL:
169 case AUDIO_STREAM_BLUETOOTH_SCO:
170 return STRATEGY_PHONE;
171 case AUDIO_STREAM_RING:
172 case AUDIO_STREAM_ALARM:
173 return STRATEGY_SONIFICATION;
174 case AUDIO_STREAM_NOTIFICATION:
175 return STRATEGY_SONIFICATION_RESPECTFUL;
176 case AUDIO_STREAM_DTMF:
177 return STRATEGY_DTMF;
178 default:
179 ALOGE("unknown stream type %d", stream);
180 case AUDIO_STREAM_SYSTEM:
181 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
182 // while key clicks are played produces a poor result
183 case AUDIO_STREAM_MUSIC:
184 return STRATEGY_MEDIA;
185 case AUDIO_STREAM_ENFORCED_AUDIBLE:
186 return STRATEGY_ENFORCED_AUDIBLE;
187 case AUDIO_STREAM_TTS:
188 return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
189 case AUDIO_STREAM_ACCESSIBILITY:
190 return STRATEGY_ACCESSIBILITY;
191 case AUDIO_STREAM_REROUTING:
192 return STRATEGY_REROUTING;
193 }
194}
195
196routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
197{
François Gaffie2110e042015-03-24 08:41:51 +0100198 // usage to strategy mapping
199 switch (usage) {
200 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
François Gaffie2110e042015-03-24 08:41:51 +0100201 return STRATEGY_ACCESSIBILITY;
202
203 case AUDIO_USAGE_MEDIA:
204 case AUDIO_USAGE_GAME:
Jean-Michel Trivi36867762016-12-29 12:03:28 -0800205 case AUDIO_USAGE_ASSISTANT:
François Gaffie2110e042015-03-24 08:41:51 +0100206 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
207 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
208 return STRATEGY_MEDIA;
209
210 case AUDIO_USAGE_VOICE_COMMUNICATION:
211 return STRATEGY_PHONE;
212
213 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
214 return STRATEGY_DTMF;
215
216 case AUDIO_USAGE_ALARM:
217 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
218 return STRATEGY_SONIFICATION;
219
220 case AUDIO_USAGE_NOTIFICATION:
221 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
222 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
223 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
224 case AUDIO_USAGE_NOTIFICATION_EVENT:
225 return STRATEGY_SONIFICATION_RESPECTFUL;
226
227 case AUDIO_USAGE_UNKNOWN:
228 default:
229 return STRATEGY_MEDIA;
230 }
231}
232
233audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
234{
Eric Laurent0f928fa2016-03-21 12:06:20 -0700235 DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
236 DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
François Gaffie2110e042015-03-24 08:41:51 +0100237
Eric Laurentc75307b2015-03-17 15:29:32 -0700238 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100239
Eric Laurent0f928fa2016-03-21 12:06:20 -0700240 return getDeviceForStrategyInt(strategy, availableOutputDevices,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800241 availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
Eric Laurent28d09f02016-03-08 10:43:05 -0800242}
243
244
Eric Laurent28d09f02016-03-08 10:43:05 -0800245audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800246 DeviceVector availableOutputDevices,
247 DeviceVector availableInputDevices,
248 const SwAudioOutputCollection &outputs,
249 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800250{
François Gaffie2110e042015-03-24 08:41:51 +0100251 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800252 uint32_t availableOutputDevicesType =
253 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100254
255 switch (strategy) {
256
257 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
258 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100259 break;
260
261 case STRATEGY_SONIFICATION_RESPECTFUL:
262 if (isInCall()) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800263 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800264 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
265 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100266 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800267 bool media_active_locally =
268 outputs.isStreamActiveLocally(
269 AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
270 || outputs.isStreamActiveLocally(
271 AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
272 // routing is same as media without the "remote" device
273 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
274 availableOutputDevices,
275 availableInputDevices, outputs,
276 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
277 // if no media is playing on the device, check for mandatory use of "safe" speaker
278 // when media would have played on speaker, and the safe speaker path is available
279 if (!media_active_locally
280 && (device & AUDIO_DEVICE_OUT_SPEAKER)
281 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700282 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
283 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
284 }
François Gaffie2110e042015-03-24 08:41:51 +0100285 }
286 break;
287
288 case STRATEGY_DTMF:
289 if (!isInCall()) {
290 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800291 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800292 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
293 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100294 break;
295 }
296 // when in call, DTMF and PHONE strategies follow the same rules
297 // FALL THROUGH
298
299 case STRATEGY_PHONE:
300 // Force use of only devices on primary output if:
301 // - in call AND
302 // - cannot route from voice call RX OR
303 // - audio HAL version is < 3.0 and TX device is on the primary HW module
304 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
305 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
306 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
307 audio_devices_t availPrimaryInputDevices =
308 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
309 audio_devices_t availPrimaryOutputDevices =
310 primaryOutput->supportedDevices() & availableOutputDevices.types();
311
312 if (((availableInputDevices.types() &
313 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
314 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700315 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100316 availableOutputDevicesType = availPrimaryOutputDevices;
317 }
318 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800319 // for phone strategy, we first consider the forced use and then the available devices by
320 // order of priority
François Gaffie2110e042015-03-24 08:41:51 +0100321 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
322 case AUDIO_POLICY_FORCE_BT_SCO:
323 if (!isInCall() || strategy != STRATEGY_DTMF) {
324 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
325 if (device) break;
326 }
327 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
328 if (device) break;
329 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
330 if (device) break;
331 // if SCO device is requested but no SCO device is available, fall back to default case
332 // FALL THROUGH
333
334 default: // FORCE_NONE
335 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
336 if (!isInCall() &&
337 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
338 (outputs.getA2dpOutput() != 0)) {
339 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
340 if (device) break;
341 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
342 if (device) break;
343 }
344 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
345 if (device) break;
346 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
347 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800348 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
349 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700350 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
351 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100352 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
353 if (device) break;
354 if (!isInCall()) {
355 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
356 if (device) break;
357 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
358 if (device) break;
359 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
360 if (device) break;
361 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
362 if (device) break;
363 }
364 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100365 break;
366
367 case AUDIO_POLICY_FORCE_SPEAKER:
368 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
369 // A2DP speaker when forcing to speaker output
370 if (!isInCall() &&
371 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
372 (outputs.getA2dpOutput() != 0)) {
373 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
374 if (device) break;
375 }
376 if (!isInCall()) {
377 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
378 if (device) break;
379 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
380 if (device) break;
381 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
382 if (device) break;
383 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
384 if (device) break;
385 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
386 if (device) break;
387 }
François Gaffie2110e042015-03-24 08:41:51 +0100388 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100389 break;
390 }
391 break;
392
393 case STRATEGY_SONIFICATION:
394
395 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
396 // handleIncallSonification().
397 if (isInCall()) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800398 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800399 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
400 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100401 break;
402 }
403 // FALL THROUGH
404
405 case STRATEGY_ENFORCED_AUDIBLE:
406 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
407 // except:
408 // - when in call where it doesn't default to STRATEGY_PHONE behavior
409 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
410
411 if ((strategy == STRATEGY_SONIFICATION) ||
412 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
413 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100414 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800415
416 // if SCO headset is connected and we are told to use it, play ringtone over
417 // speaker and BT SCO
418 if (((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) &&
419 (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO)) {
420 uint32_t device2 = AUDIO_DEVICE_NONE;
421 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
422 if (device2 == AUDIO_DEVICE_NONE) {
423 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
424 }
425 if (device2 == AUDIO_DEVICE_NONE) {
426 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
427 }
428
429 if (device2 != AUDIO_DEVICE_NONE) {
430 device |= device2;
431 break;
432 }
433 }
François Gaffie2110e042015-03-24 08:41:51 +0100434 // The second device used for sonification is the same as the device used by media strategy
435 // FALL THROUGH
436
François Gaffie2110e042015-03-24 08:41:51 +0100437 case STRATEGY_ACCESSIBILITY:
438 if (strategy == STRATEGY_ACCESSIBILITY) {
439 // do not route accessibility prompts to a digital output currently configured with a
440 // compressed format as they would likely not be mixed and dropped.
441 for (size_t i = 0; i < outputs.size(); i++) {
442 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
443 audio_devices_t devices = desc->device() &
444 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
445 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
446 devices != AUDIO_DEVICE_NONE) {
447 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
448 }
449 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800450 availableOutputDevices =
451 availableOutputDevices.getDevicesFromType(availableOutputDevicesType);
452 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
453 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
454 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800455 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
456 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800457 }
458 if (isInCall()) {
459 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800460 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
461 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800462 }
François Gaffie2110e042015-03-24 08:41:51 +0100463 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800464 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
François Gaffie2110e042015-03-24 08:41:51 +0100465 // FALL THROUGH
466
Eric Laurent28d09f02016-03-08 10:43:05 -0800467 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100468 case STRATEGY_REROUTING:
469 case STRATEGY_MEDIA: {
470 uint32_t device2 = AUDIO_DEVICE_NONE;
471 if (strategy != STRATEGY_SONIFICATION) {
472 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800473 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
474 String8("0")) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100475 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
476 }
477 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700478 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800479 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800480 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
481 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700482 break;
483 }
François Gaffie2110e042015-03-24 08:41:51 +0100484 if ((device2 == AUDIO_DEVICE_NONE) &&
485 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
486 (outputs.getA2dpOutput() != 0)) {
487 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
488 if (device2 == AUDIO_DEVICE_NONE) {
489 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
490 }
491 if (device2 == AUDIO_DEVICE_NONE) {
492 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
493 }
494 }
495 if ((device2 == AUDIO_DEVICE_NONE) &&
496 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
497 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
498 }
499 if (device2 == AUDIO_DEVICE_NONE) {
500 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
501 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700502 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100503 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
504 }
505 if (device2 == AUDIO_DEVICE_NONE) {
506 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
507 }
508 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700509 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
510 }
511 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100512 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
513 }
514 if (device2 == AUDIO_DEVICE_NONE) {
515 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
516 }
517 if (device2 == AUDIO_DEVICE_NONE) {
518 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
519 }
520 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
521 // no sonification on aux digital (e.g. HDMI)
522 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
523 }
524 if ((device2 == AUDIO_DEVICE_NONE) &&
525 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
526 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
527 }
528 if (device2 == AUDIO_DEVICE_NONE) {
529 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
530 }
531 int device3 = AUDIO_DEVICE_NONE;
532 if (strategy == STRATEGY_MEDIA) {
533 // ARC, SPDIF and AUX_LINE can co-exist with others.
534 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
535 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
536 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
537 }
538
539 device2 |= device3;
540 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
541 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
542 device |= device2;
543
544 // If hdmi system audio mode is on, remove speaker out of output list.
545 if ((strategy == STRATEGY_MEDIA) &&
546 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
547 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
548 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
549 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700550
551 // for STRATEGY_SONIFICATION:
552 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
553 if ((strategy == STRATEGY_SONIFICATION) &&
554 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
555 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
556 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
557 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
558 }
François Gaffie2110e042015-03-24 08:41:51 +0100559 } break;
560
561 default:
562 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
563 break;
564 }
565
Eric Laurent5a2b6292016-04-14 18:05:57 -0700566 if (device == AUDIO_DEVICE_NONE) {
567 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
568 device = mApmObserver->getDefaultOutputDevice()->type();
569 ALOGE_IF(device == AUDIO_DEVICE_NONE,
570 "getDeviceForStrategy() no default device defined");
571 }
François Gaffie2110e042015-03-24 08:41:51 +0100572 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
573 return device;
574}
575
576
577audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
578{
579 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
580 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
Eric Laurentc75307b2015-03-17 15:29:32 -0700581 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100582 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
583
584 uint32_t device = AUDIO_DEVICE_NONE;
585
586 switch (inputSource) {
587 case AUDIO_SOURCE_VOICE_UPLINK:
588 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
589 device = AUDIO_DEVICE_IN_VOICE_CALL;
590 break;
591 }
592 break;
593
594 case AUDIO_SOURCE_DEFAULT:
595 case AUDIO_SOURCE_MIC:
596 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
597 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
598 } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
599 (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
612 case AUDIO_SOURCE_VOICE_COMMUNICATION:
613 // Allow only use of devices on primary input if in call and HAL does not support routing
614 // to voice call path.
615 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
616 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
617 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
618 availableDeviceTypes =
619 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
620 & ~AUDIO_DEVICE_BIT_IN;
621 }
622
623 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
624 case AUDIO_POLICY_FORCE_BT_SCO:
625 // if SCO device is requested but no SCO device is available, fall back to default case
626 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
627 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
628 break;
629 }
630 // FALL THROUGH
631
632 default: // FORCE_NONE
633 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
634 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700635 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
636 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100637 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
638 device = AUDIO_DEVICE_IN_USB_DEVICE;
639 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
640 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
641 }
642 break;
643
644 case AUDIO_POLICY_FORCE_SPEAKER:
645 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
646 device = AUDIO_DEVICE_IN_BACK_MIC;
647 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
648 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
649 }
650 break;
651 }
652 break;
653
654 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800655 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100656 case AUDIO_SOURCE_HOTWORD:
657 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
658 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
659 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
660 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
661 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700662 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
663 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100664 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
665 device = AUDIO_DEVICE_IN_USB_DEVICE;
666 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
667 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
668 }
669 break;
670 case AUDIO_SOURCE_CAMCORDER:
671 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
672 device = AUDIO_DEVICE_IN_BACK_MIC;
673 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
674 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
675 }
676 break;
677 case AUDIO_SOURCE_VOICE_DOWNLINK:
678 case AUDIO_SOURCE_VOICE_CALL:
679 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
680 device = AUDIO_DEVICE_IN_VOICE_CALL;
681 }
682 break;
683 case AUDIO_SOURCE_REMOTE_SUBMIX:
684 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
685 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
686 }
687 break;
688 case AUDIO_SOURCE_FM_TUNER:
689 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
690 device = AUDIO_DEVICE_IN_FM_TUNER;
691 }
692 break;
693 default:
694 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
695 break;
696 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700697 if (device == AUDIO_DEVICE_NONE) {
698 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
699 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
700 device = AUDIO_DEVICE_IN_STUB;
701 }
702 ALOGE_IF(device == AUDIO_DEVICE_NONE,
703 "getDeviceForInputSource() no default device defined");
704 }
François Gaffie2110e042015-03-24 08:41:51 +0100705 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
706 return device;
707}
708
709template <>
710AudioPolicyManagerInterface *Engine::queryInterface()
711{
712 return &mManagerInterface;
713}
714
715} // namespace audio_policy
716} // namespace android
717
718