blob: 06864140b9731c8c2ddb60591bddd50501500a29 [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"
28#include "Gains.h"
29#include <AudioPolicyManagerObserver.h>
30#include <AudioPort.h>
31#include <IOProfile.h>
32#include <policy.h>
33#include <utils/String8.h>
34#include <utils/Log.h>
35
36namespace android
37{
38namespace audio_policy
39{
40
41Engine::Engine()
42 : mManagerInterface(this),
43 mPhoneState(AUDIO_MODE_NORMAL),
44 mApmObserver(NULL)
45{
46 for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
47 mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
48 }
49}
50
51Engine::~Engine()
52{
53}
54
55void Engine::setObserver(AudioPolicyManagerObserver *observer)
56{
57 ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
58 mApmObserver = observer;
59}
60
61status_t Engine::initCheck()
62{
63 return (mApmObserver != NULL) ? NO_ERROR : NO_INIT;
64}
65
Eric Laurentffbc80f2015-03-18 18:30:19 -070066float Engine::volIndexToDb(Volume::device_category category, audio_stream_type_t streamType,
François Gaffie2110e042015-03-24 08:41:51 +010067 int indexInUi)
68{
69 const StreamDescriptor &streamDesc = mApmObserver->getStreamDescriptors().valueAt(streamType);
Eric Laurentffbc80f2015-03-18 18:30:19 -070070 return Gains::volIndexToDb(category, streamDesc, indexInUi);
François Gaffie2110e042015-03-24 08:41:51 +010071}
72
Eric Laurentffbc80f2015-03-18 18:30:19 -070073
François Gaffie2110e042015-03-24 08:41:51 +010074status_t Engine::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
75{
76 ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
77 if (indexMin < 0 || indexMin >= indexMax) {
78 ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d",
79 stream , indexMin, indexMax);
80 return BAD_VALUE;
81 }
82 mApmObserver->getStreamDescriptors().setVolumeIndexMin(stream, indexMin);
83 mApmObserver->getStreamDescriptors().setVolumeIndexMax(stream, indexMax);
84 return NO_ERROR;
85}
86
87void Engine::initializeVolumeCurves(bool isSpeakerDrcEnabled)
88{
89 StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors();
90
91 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
92 for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
93 streams.setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
94 static_cast<Volume::device_category>(j),
95 Gains::sVolumeProfiles[i][j]);
96 }
97 }
98
99 // Check availability of DRC on speaker path: if available, override some of the speaker curves
100 if (isSpeakerDrcEnabled) {
101 streams.setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, Volume::DEVICE_CATEGORY_SPEAKER,
102 Gains::sDefaultSystemVolumeCurveDrc);
103 streams.setVolumeCurvePoint(AUDIO_STREAM_RING, Volume::DEVICE_CATEGORY_SPEAKER,
104 Gains::sSpeakerSonificationVolumeCurveDrc);
105 streams.setVolumeCurvePoint(AUDIO_STREAM_ALARM, Volume::DEVICE_CATEGORY_SPEAKER,
106 Gains::sSpeakerSonificationVolumeCurveDrc);
107 streams.setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, Volume::DEVICE_CATEGORY_SPEAKER,
108 Gains::sSpeakerSonificationVolumeCurveDrc);
109 streams.setVolumeCurvePoint(AUDIO_STREAM_MUSIC, Volume::DEVICE_CATEGORY_SPEAKER,
110 Gains::sSpeakerMediaVolumeCurveDrc);
111 streams.setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, Volume::DEVICE_CATEGORY_SPEAKER,
112 Gains::sSpeakerMediaVolumeCurveDrc);
113 }
114}
115
116
117status_t Engine::setPhoneState(audio_mode_t state)
118{
119 ALOGV("setPhoneState() state %d", state);
120
121 if (state < 0 || state >= AUDIO_MODE_CNT) {
122 ALOGW("setPhoneState() invalid state %d", state);
123 return BAD_VALUE;
124 }
125
126 if (state == mPhoneState ) {
127 ALOGW("setPhoneState() setting same state %d", state);
128 return BAD_VALUE;
129 }
130
131 // store previous phone state for management of sonification strategy below
132 int oldState = mPhoneState;
133 mPhoneState = state;
134 StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors();
135 // are we entering or starting a call
136 if (!is_state_in_call(oldState) && is_state_in_call(state)) {
137 ALOGV(" Entering call in setPhoneState()");
138 for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
139 streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j),
140 Gains::sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]);
141 }
142 } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
143 ALOGV(" Exiting call in setPhoneState()");
144 for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
145 streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j),
146 Gains::sVolumeProfiles[AUDIO_STREAM_DTMF][j]);
147 }
148 }
149 return NO_ERROR;
150}
151
152status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
153{
154 switch(usage) {
155 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
156 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
157 config != AUDIO_POLICY_FORCE_NONE) {
158 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
159 return BAD_VALUE;
160 }
161 mForceUse[usage] = config;
162 break;
163 case AUDIO_POLICY_FORCE_FOR_MEDIA:
164 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
165 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
166 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
167 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
168 config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
169 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
170 return BAD_VALUE;
171 }
172 mForceUse[usage] = config;
173 break;
174 case AUDIO_POLICY_FORCE_FOR_RECORD:
175 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
176 config != AUDIO_POLICY_FORCE_NONE) {
177 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
178 return BAD_VALUE;
179 }
180 mForceUse[usage] = config;
181 break;
182 case AUDIO_POLICY_FORCE_FOR_DOCK:
183 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
184 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
185 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
186 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
187 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
188 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
189 }
190 mForceUse[usage] = config;
191 break;
192 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
193 if (config != AUDIO_POLICY_FORCE_NONE &&
194 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
195 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
196 }
197 mForceUse[usage] = config;
198 break;
199 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
200 if (config != AUDIO_POLICY_FORCE_NONE &&
201 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
202 ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config);
203 }
204 mForceUse[usage] = config;
205 break;
206 default:
207 ALOGW("setForceUse() invalid usage %d", usage);
208 break;
209 }
210 return NO_ERROR;
211}
212
213routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
214{
215 // stream to strategy mapping
216 switch (stream) {
217 case AUDIO_STREAM_VOICE_CALL:
218 case AUDIO_STREAM_BLUETOOTH_SCO:
219 return STRATEGY_PHONE;
220 case AUDIO_STREAM_RING:
221 case AUDIO_STREAM_ALARM:
222 return STRATEGY_SONIFICATION;
223 case AUDIO_STREAM_NOTIFICATION:
224 return STRATEGY_SONIFICATION_RESPECTFUL;
225 case AUDIO_STREAM_DTMF:
226 return STRATEGY_DTMF;
227 default:
228 ALOGE("unknown stream type %d", stream);
229 case AUDIO_STREAM_SYSTEM:
230 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
231 // while key clicks are played produces a poor result
232 case AUDIO_STREAM_MUSIC:
233 return STRATEGY_MEDIA;
234 case AUDIO_STREAM_ENFORCED_AUDIBLE:
235 return STRATEGY_ENFORCED_AUDIBLE;
236 case AUDIO_STREAM_TTS:
237 return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
238 case AUDIO_STREAM_ACCESSIBILITY:
239 return STRATEGY_ACCESSIBILITY;
240 case AUDIO_STREAM_REROUTING:
241 return STRATEGY_REROUTING;
242 }
243}
244
245routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
246{
Eric Laurentc75307b2015-03-17 15:29:32 -0700247 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100248
249 // usage to strategy mapping
250 switch (usage) {
251 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
252 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
253 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
254 return STRATEGY_SONIFICATION;
255 }
256 if (isInCall()) {
257 return STRATEGY_PHONE;
258 }
259 return STRATEGY_ACCESSIBILITY;
260
261 case AUDIO_USAGE_MEDIA:
262 case AUDIO_USAGE_GAME:
263 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
264 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
265 return STRATEGY_MEDIA;
266
267 case AUDIO_USAGE_VOICE_COMMUNICATION:
268 return STRATEGY_PHONE;
269
270 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
271 return STRATEGY_DTMF;
272
273 case AUDIO_USAGE_ALARM:
274 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
275 return STRATEGY_SONIFICATION;
276
277 case AUDIO_USAGE_NOTIFICATION:
278 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
279 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
280 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
281 case AUDIO_USAGE_NOTIFICATION_EVENT:
282 return STRATEGY_SONIFICATION_RESPECTFUL;
283
284 case AUDIO_USAGE_UNKNOWN:
285 default:
286 return STRATEGY_MEDIA;
287 }
288}
289
290audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
291{
292 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
293 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
294
Eric Laurentc75307b2015-03-17 15:29:32 -0700295 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100296
297 uint32_t device = AUDIO_DEVICE_NONE;
298 uint32_t availableOutputDevicesType = availableOutputDevices.types();
299
300 switch (strategy) {
301
302 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
303 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
304 if (!device) {
305 ALOGE("getDeviceForStrategy() no device found for "\
306 "STRATEGY_TRANSMITTED_THROUGH_SPEAKER");
307 }
308 break;
309
310 case STRATEGY_SONIFICATION_RESPECTFUL:
311 if (isInCall()) {
312 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
313 } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
314 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
315 // while media is playing on a remote device, use the the sonification behavior.
316 // Note that we test this usecase before testing if media is playing because
317 // the isStreamActive() method only informs about the activity of a stream, not
318 // if it's for local playback. Note also that we use the same delay between both tests
319 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
320 //user "safe" speaker if available instead of normal speaker to avoid triggering
321 //other acoustic safety mechanisms for notification
Eric Laurent9a7d9222015-07-02 15:30:23 -0700322 if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
323 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
324 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
325 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
326 }
François Gaffie2110e042015-03-24 08:41:51 +0100327 } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
328 // while media is playing (or has recently played), use the same device
329 device = getDeviceForStrategy(STRATEGY_MEDIA);
330 } else {
331 // when media is not playing anymore, fall back on the sonification behavior
332 device = getDeviceForStrategy(STRATEGY_SONIFICATION);
333 //user "safe" speaker if available instead of normal speaker to avoid triggering
334 //other acoustic safety mechanisms for notification
Eric Laurent9a7d9222015-07-02 15:30:23 -0700335 if ((device & AUDIO_DEVICE_OUT_SPEAKER) &&
336 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
337 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
338 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
339 }
François Gaffie2110e042015-03-24 08:41:51 +0100340 }
341 break;
342
343 case STRATEGY_DTMF:
344 if (!isInCall()) {
345 // when off call, DTMF strategy follows the same rules as MEDIA strategy
346 device = getDeviceForStrategy(STRATEGY_MEDIA);
347 break;
348 }
349 // when in call, DTMF and PHONE strategies follow the same rules
350 // FALL THROUGH
351
352 case STRATEGY_PHONE:
353 // Force use of only devices on primary output if:
354 // - in call AND
355 // - cannot route from voice call RX OR
356 // - audio HAL version is < 3.0 and TX device is on the primary HW module
357 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
358 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
359 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
360 audio_devices_t availPrimaryInputDevices =
361 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
362 audio_devices_t availPrimaryOutputDevices =
363 primaryOutput->supportedDevices() & availableOutputDevices.types();
364
365 if (((availableInputDevices.types() &
366 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
367 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Eric Laurent322b4d22015-04-03 15:57:54 -0700368 (primaryOutput->getAudioPort()->getModuleVersion() <
François Gaffie2110e042015-03-24 08:41:51 +0100369 AUDIO_DEVICE_API_VERSION_3_0))) {
370 availableOutputDevicesType = availPrimaryOutputDevices;
371 }
372 }
373 // for phone strategy, we first consider the forced use and then the available devices by order
374 // of priority
375 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
376 case AUDIO_POLICY_FORCE_BT_SCO:
377 if (!isInCall() || strategy != STRATEGY_DTMF) {
378 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
379 if (device) break;
380 }
381 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
382 if (device) break;
383 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
384 if (device) break;
385 // if SCO device is requested but no SCO device is available, fall back to default case
386 // FALL THROUGH
387
388 default: // FORCE_NONE
389 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
390 if (!isInCall() &&
391 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
392 (outputs.getA2dpOutput() != 0)) {
393 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
394 if (device) break;
395 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
396 if (device) break;
397 }
398 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
399 if (device) break;
400 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
401 if (device) break;
402 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
403 if (device) break;
404 if (!isInCall()) {
405 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
406 if (device) break;
407 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
408 if (device) break;
409 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
410 if (device) break;
411 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
412 if (device) break;
413 }
414 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
415 if (device) break;
416 device = mApmObserver->getDefaultOutputDevice()->type();
417 if (device == AUDIO_DEVICE_NONE) {
418 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
419 }
420 break;
421
422 case AUDIO_POLICY_FORCE_SPEAKER:
423 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
424 // A2DP speaker when forcing to speaker output
425 if (!isInCall() &&
426 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
427 (outputs.getA2dpOutput() != 0)) {
428 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
429 if (device) break;
430 }
431 if (!isInCall()) {
432 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
433 if (device) break;
434 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
435 if (device) break;
436 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
437 if (device) break;
438 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
439 if (device) break;
440 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
441 if (device) break;
442 }
443 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
444 if (device) break;
445 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
446 if (device) break;
447 device = mApmObserver->getDefaultOutputDevice()->type();
448 if (device == AUDIO_DEVICE_NONE) {
449 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
450 }
451 break;
452 }
453 break;
454
455 case STRATEGY_SONIFICATION:
456
457 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
458 // handleIncallSonification().
459 if (isInCall()) {
460 device = getDeviceForStrategy(STRATEGY_PHONE);
461 break;
462 }
463 // FALL THROUGH
464
465 case STRATEGY_ENFORCED_AUDIBLE:
466 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
467 // except:
468 // - when in call where it doesn't default to STRATEGY_PHONE behavior
469 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
470
471 if ((strategy == STRATEGY_SONIFICATION) ||
472 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
473 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
474 if (device == AUDIO_DEVICE_NONE) {
475 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
476 }
477 }
478 // The second device used for sonification is the same as the device used by media strategy
479 // FALL THROUGH
480
481 // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now
482 case STRATEGY_ACCESSIBILITY:
483 if (strategy == STRATEGY_ACCESSIBILITY) {
484 // do not route accessibility prompts to a digital output currently configured with a
485 // compressed format as they would likely not be mixed and dropped.
486 for (size_t i = 0; i < outputs.size(); i++) {
487 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
488 audio_devices_t devices = desc->device() &
489 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
490 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
491 devices != AUDIO_DEVICE_NONE) {
492 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
493 }
494 }
495 }
496 // FALL THROUGH
497
498 case STRATEGY_REROUTING:
499 case STRATEGY_MEDIA: {
500 uint32_t device2 = AUDIO_DEVICE_NONE;
501 if (strategy != STRATEGY_SONIFICATION) {
502 // no sonification on remote submix (e.g. WFD)
503 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
504 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
505 }
506 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700507 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
508 device = getDeviceForStrategy(STRATEGY_PHONE);
509 break;
510 }
François Gaffie2110e042015-03-24 08:41:51 +0100511 if ((device2 == AUDIO_DEVICE_NONE) &&
512 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
513 (outputs.getA2dpOutput() != 0)) {
514 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
515 if (device2 == AUDIO_DEVICE_NONE) {
516 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
517 }
518 if (device2 == AUDIO_DEVICE_NONE) {
519 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
520 }
521 }
522 if ((device2 == AUDIO_DEVICE_NONE) &&
523 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
524 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
525 }
526 if (device2 == AUDIO_DEVICE_NONE) {
527 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
528 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700529 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100530 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
531 }
532 if (device2 == AUDIO_DEVICE_NONE) {
533 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
534 }
535 if (device2 == AUDIO_DEVICE_NONE) {
536 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
537 }
538 if (device2 == AUDIO_DEVICE_NONE) {
539 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
540 }
541 if (device2 == AUDIO_DEVICE_NONE) {
542 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
543 }
544 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
545 // no sonification on aux digital (e.g. HDMI)
546 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
547 }
548 if ((device2 == AUDIO_DEVICE_NONE) &&
549 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
550 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
551 }
552 if (device2 == AUDIO_DEVICE_NONE) {
553 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
554 }
555 int device3 = AUDIO_DEVICE_NONE;
556 if (strategy == STRATEGY_MEDIA) {
557 // ARC, SPDIF and AUX_LINE can co-exist with others.
558 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
559 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
560 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
561 }
562
563 device2 |= device3;
564 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
565 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
566 device |= device2;
567
568 // If hdmi system audio mode is on, remove speaker out of output list.
569 if ((strategy == STRATEGY_MEDIA) &&
570 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
571 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
572 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
573 }
574
575 if (device) break;
576 device = mApmObserver->getDefaultOutputDevice()->type();
577 if (device == AUDIO_DEVICE_NONE) {
578 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
579 }
580 } break;
581
582 default:
583 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
584 break;
585 }
586
587 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
588 return device;
589}
590
591
592audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
593{
594 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
595 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
Eric Laurentc75307b2015-03-17 15:29:32 -0700596 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100597 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
598
599 uint32_t device = AUDIO_DEVICE_NONE;
600
601 switch (inputSource) {
602 case AUDIO_SOURCE_VOICE_UPLINK:
603 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
604 device = AUDIO_DEVICE_IN_VOICE_CALL;
605 break;
606 }
607 break;
608
609 case AUDIO_SOURCE_DEFAULT:
610 case AUDIO_SOURCE_MIC:
611 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
612 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
613 } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
614 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
615 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
616 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
617 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
618 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
619 device = AUDIO_DEVICE_IN_USB_DEVICE;
620 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
621 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
622 }
623 break;
624
625 case AUDIO_SOURCE_VOICE_COMMUNICATION:
626 // Allow only use of devices on primary input if in call and HAL does not support routing
627 // to voice call path.
628 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
629 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
630 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
631 availableDeviceTypes =
632 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
633 & ~AUDIO_DEVICE_BIT_IN;
634 }
635
636 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
637 case AUDIO_POLICY_FORCE_BT_SCO:
638 // if SCO device is requested but no SCO device is available, fall back to default case
639 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
640 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
641 break;
642 }
643 // FALL THROUGH
644
645 default: // FORCE_NONE
646 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
647 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
648 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
649 device = AUDIO_DEVICE_IN_USB_DEVICE;
650 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
651 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
652 }
653 break;
654
655 case AUDIO_POLICY_FORCE_SPEAKER:
656 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
657 device = AUDIO_DEVICE_IN_BACK_MIC;
658 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
659 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
660 }
661 break;
662 }
663 break;
664
665 case AUDIO_SOURCE_VOICE_RECOGNITION:
666 case AUDIO_SOURCE_HOTWORD:
667 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
668 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
669 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
670 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
671 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
672 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
673 device = AUDIO_DEVICE_IN_USB_DEVICE;
674 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
675 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
676 }
677 break;
678 case AUDIO_SOURCE_CAMCORDER:
679 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
680 device = AUDIO_DEVICE_IN_BACK_MIC;
681 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
682 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
683 }
684 break;
685 case AUDIO_SOURCE_VOICE_DOWNLINK:
686 case AUDIO_SOURCE_VOICE_CALL:
687 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
688 device = AUDIO_DEVICE_IN_VOICE_CALL;
689 }
690 break;
691 case AUDIO_SOURCE_REMOTE_SUBMIX:
692 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
693 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
694 }
695 break;
696 case AUDIO_SOURCE_FM_TUNER:
697 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
698 device = AUDIO_DEVICE_IN_FM_TUNER;
699 }
700 break;
701 default:
702 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
703 break;
704 }
705 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