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