blob: 43664e6142531a4b18cbc6e68ce0b8962097c13f [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{
Eric Laurentc75307b2015-03-17 15:29:32 -0700198 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100199
200 // usage to strategy mapping
201 switch (usage) {
202 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
203 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
204 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
205 return STRATEGY_SONIFICATION;
206 }
207 if (isInCall()) {
208 return STRATEGY_PHONE;
209 }
210 return STRATEGY_ACCESSIBILITY;
211
212 case AUDIO_USAGE_MEDIA:
213 case AUDIO_USAGE_GAME:
214 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{
243 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
244 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
245
Eric Laurentc75307b2015-03-17 15:29:32 -0700246 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100247
248 uint32_t device = AUDIO_DEVICE_NONE;
249 uint32_t availableOutputDevicesType = availableOutputDevices.types();
250
251 switch (strategy) {
252
253 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
254 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
255 if (!device) {
256 ALOGE("getDeviceForStrategy() no device found for "\
257 "STRATEGY_TRANSMITTED_THROUGH_SPEAKER");
258 }
259 break;
260
261 case STRATEGY_SONIFICATION_RESPECTFUL:
262 if (isInCall()) {
263 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
264 } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
265 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
266 // while media is playing on a remote device, use the the sonification behavior.
267 // Note that we test this usecase before testing if media is playing because
268 // the isStreamActive() method only informs about the activity of a stream, not
269 // if it's for local playback. Note also that we use the same delay between both tests
270 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
271 //user "safe" speaker if available instead of normal speaker to avoid triggering
272 //other acoustic safety mechanisms for notification
Eric Laurent9a7d9222015-07-02 15:30:23 -0700273 if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
274 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
275 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
276 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
277 }
François Gaffie2110e042015-03-24 08:41:51 +0100278 } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
279 // while media is playing (or has recently played), use the same device
280 device = getDeviceForStrategy(STRATEGY_MEDIA);
281 } else {
282 // when media is not playing anymore, fall back on the sonification behavior
283 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
284 //user "safe" speaker if available instead of normal speaker to avoid triggering
285 //other acoustic safety mechanisms for notification
Eric Laurent9a7d9222015-07-02 15:30:23 -0700286 if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
287 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
288 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
289 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
290 }
François Gaffie2110e042015-03-24 08:41:51 +0100291 }
292 break;
293
294 case STRATEGY_DTMF:
295 if (!isInCall()) {
296 // when off call, DTMF strategy follows the same rules as MEDIA strategy
297 device = getDeviceForStrategy(STRATEGY_MEDIA);
298 break;
299 }
300 // when in call, DTMF and PHONE strategies follow the same rules
301 // FALL THROUGH
302
303 case STRATEGY_PHONE:
304 // Force use of only devices on primary output if:
305 // - in call AND
306 // - cannot route from voice call RX OR
307 // - audio HAL version is < 3.0 and TX device is on the primary HW module
308 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
309 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
310 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
311 audio_devices_t availPrimaryInputDevices =
312 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
313 audio_devices_t availPrimaryOutputDevices =
314 primaryOutput->supportedDevices() & availableOutputDevices.types();
315
316 if (((availableInputDevices.types() &
317 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
318 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Eric Laurent322b4d22015-04-03 15:57:54 -0700319 (primaryOutput->getAudioPort()->getModuleVersion() <
François Gaffie2110e042015-03-24 08:41:51 +0100320 AUDIO_DEVICE_API_VERSION_3_0))) {
321 availableOutputDevicesType = availPrimaryOutputDevices;
322 }
323 }
324 // for phone strategy, we first consider the forced use and then the available devices by order
325 // of priority
326 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
327 case AUDIO_POLICY_FORCE_BT_SCO:
328 if (!isInCall() || strategy != STRATEGY_DTMF) {
329 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
330 if (device) break;
331 }
332 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
333 if (device) break;
334 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
335 if (device) break;
336 // if SCO device is requested but no SCO device is available, fall back to default case
337 // FALL THROUGH
338
339 default: // FORCE_NONE
340 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
341 if (!isInCall() &&
342 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
343 (outputs.getA2dpOutput() != 0)) {
344 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
345 if (device) break;
346 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
347 if (device) break;
348 }
349 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
350 if (device) break;
351 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
352 if (device) break;
353 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
354 if (device) break;
355 if (!isInCall()) {
356 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
357 if (device) break;
358 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
359 if (device) break;
360 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
361 if (device) break;
362 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
363 if (device) break;
364 }
365 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
366 if (device) break;
367 device = mApmObserver->getDefaultOutputDevice()->type();
368 if (device == AUDIO_DEVICE_NONE) {
369 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
370 }
371 break;
372
373 case AUDIO_POLICY_FORCE_SPEAKER:
374 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
375 // A2DP speaker when forcing to speaker output
376 if (!isInCall() &&
377 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
378 (outputs.getA2dpOutput() != 0)) {
379 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
380 if (device) break;
381 }
382 if (!isInCall()) {
383 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
384 if (device) break;
385 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
386 if (device) break;
387 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
388 if (device) break;
389 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
390 if (device) break;
391 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
392 if (device) break;
393 }
394 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
395 if (device) break;
396 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
397 if (device) break;
398 device = mApmObserver->getDefaultOutputDevice()->type();
399 if (device == AUDIO_DEVICE_NONE) {
400 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
401 }
402 break;
403 }
404 break;
405
406 case STRATEGY_SONIFICATION:
407
408 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
409 // handleIncallSonification().
410 if (isInCall()) {
411 device = getDeviceForStrategy(STRATEGY_PHONE);
412 break;
413 }
414 // FALL THROUGH
415
416 case STRATEGY_ENFORCED_AUDIBLE:
417 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
418 // except:
419 // - when in call where it doesn't default to STRATEGY_PHONE behavior
420 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
421
422 if ((strategy == STRATEGY_SONIFICATION) ||
423 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
424 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
425 if (device == AUDIO_DEVICE_NONE) {
426 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
427 }
428 }
429 // The second device used for sonification is the same as the device used by media strategy
430 // FALL THROUGH
431
432 // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now
433 case STRATEGY_ACCESSIBILITY:
434 if (strategy == STRATEGY_ACCESSIBILITY) {
435 // do not route accessibility prompts to a digital output currently configured with a
436 // compressed format as they would likely not be mixed and dropped.
437 for (size_t i = 0; i < outputs.size(); i++) {
438 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
439 audio_devices_t devices = desc->device() &
440 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
441 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
442 devices != AUDIO_DEVICE_NONE) {
443 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
444 }
445 }
446 }
447 // FALL THROUGH
448
449 case STRATEGY_REROUTING:
450 case STRATEGY_MEDIA: {
451 uint32_t device2 = AUDIO_DEVICE_NONE;
452 if (strategy != STRATEGY_SONIFICATION) {
453 // no sonification on remote submix (e.g. WFD)
454 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
455 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
456 }
457 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700458 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
459 device = getDeviceForStrategy(STRATEGY_PHONE);
460 break;
461 }
François Gaffie2110e042015-03-24 08:41:51 +0100462 if ((device2 == AUDIO_DEVICE_NONE) &&
463 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
464 (outputs.getA2dpOutput() != 0)) {
465 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
466 if (device2 == AUDIO_DEVICE_NONE) {
467 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
468 }
469 if (device2 == AUDIO_DEVICE_NONE) {
470 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
471 }
472 }
473 if ((device2 == AUDIO_DEVICE_NONE) &&
474 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
475 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
476 }
477 if (device2 == AUDIO_DEVICE_NONE) {
478 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
479 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700480 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100481 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
482 }
483 if (device2 == AUDIO_DEVICE_NONE) {
484 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
485 }
486 if (device2 == AUDIO_DEVICE_NONE) {
487 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
488 }
489 if (device2 == AUDIO_DEVICE_NONE) {
490 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
491 }
492 if (device2 == AUDIO_DEVICE_NONE) {
493 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
494 }
495 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
496 // no sonification on aux digital (e.g. HDMI)
497 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
498 }
499 if ((device2 == AUDIO_DEVICE_NONE) &&
500 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
501 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
502 }
503 if (device2 == AUDIO_DEVICE_NONE) {
504 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
505 }
506 int device3 = AUDIO_DEVICE_NONE;
507 if (strategy == STRATEGY_MEDIA) {
508 // ARC, SPDIF and AUX_LINE can co-exist with others.
509 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
510 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
511 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
512 }
513
514 device2 |= device3;
515 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
516 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
517 device |= device2;
518
519 // If hdmi system audio mode is on, remove speaker out of output list.
520 if ((strategy == STRATEGY_MEDIA) &&
521 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
522 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
523 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
524 }
525
526 if (device) break;
527 device = mApmObserver->getDefaultOutputDevice()->type();
528 if (device == AUDIO_DEVICE_NONE) {
529 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
530 }
531 } break;
532
533 default:
534 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
535 break;
536 }
537
538 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
539 return device;
540}
541
542
543audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
544{
545 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
546 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
Eric Laurentc75307b2015-03-17 15:29:32 -0700547 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100548 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
549
550 uint32_t device = AUDIO_DEVICE_NONE;
551
552 switch (inputSource) {
553 case AUDIO_SOURCE_VOICE_UPLINK:
554 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
555 device = AUDIO_DEVICE_IN_VOICE_CALL;
556 break;
557 }
558 break;
559
560 case AUDIO_SOURCE_DEFAULT:
561 case AUDIO_SOURCE_MIC:
562 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
563 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
564 } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
565 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
566 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
567 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
568 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
569 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
570 device = AUDIO_DEVICE_IN_USB_DEVICE;
571 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
572 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
573 }
574 break;
575
576 case AUDIO_SOURCE_VOICE_COMMUNICATION:
577 // Allow only use of devices on primary input if in call and HAL does not support routing
578 // to voice call path.
579 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
580 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
581 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
582 availableDeviceTypes =
583 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
584 & ~AUDIO_DEVICE_BIT_IN;
585 }
586
587 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
588 case AUDIO_POLICY_FORCE_BT_SCO:
589 // if SCO device is requested but no SCO device is available, fall back to default case
590 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
591 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
592 break;
593 }
594 // FALL THROUGH
595
596 default: // FORCE_NONE
597 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
598 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
599 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
600 device = AUDIO_DEVICE_IN_USB_DEVICE;
601 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
602 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
603 }
604 break;
605
606 case AUDIO_POLICY_FORCE_SPEAKER:
607 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
608 device = AUDIO_DEVICE_IN_BACK_MIC;
609 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
610 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
611 }
612 break;
613 }
614 break;
615
616 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800617 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100618 case AUDIO_SOURCE_HOTWORD:
619 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
620 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
621 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
622 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
623 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
624 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
625 device = AUDIO_DEVICE_IN_USB_DEVICE;
626 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
627 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
628 }
629 break;
630 case AUDIO_SOURCE_CAMCORDER:
631 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
632 device = AUDIO_DEVICE_IN_BACK_MIC;
633 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
634 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
635 }
636 break;
637 case AUDIO_SOURCE_VOICE_DOWNLINK:
638 case AUDIO_SOURCE_VOICE_CALL:
639 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
640 device = AUDIO_DEVICE_IN_VOICE_CALL;
641 }
642 break;
643 case AUDIO_SOURCE_REMOTE_SUBMIX:
644 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
645 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
646 }
647 break;
648 case AUDIO_SOURCE_FM_TUNER:
649 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
650 device = AUDIO_DEVICE_IN_FM_TUNER;
651 }
652 break;
653 default:
654 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
655 break;
656 }
657 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
658 return device;
659}
660
661template <>
662AudioPolicyManagerInterface *Engine::queryInterface()
663{
664 return &mManagerInterface;
665}
666
667} // namespace audio_policy
668} // namespace android
669
670