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