blob: be7f7ec2122040c2b9f25ffa75eb515f9d39e605 [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;
Jack He96117ae2018-02-12 20:52:53 -0800157 case AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING:
158 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_NONE) {
159 ALOGW("setForceUse() invalid config %d for FOR_VIBRATE_RINGING", config);
160 return BAD_VALUE;
161 }
162 mForceUse[usage] = config;
163 break;
François Gaffie2110e042015-03-24 08:41:51 +0100164 default:
165 ALOGW("setForceUse() invalid usage %d", usage);
Phil Burk09bc4612016-02-24 15:58:15 -0800166 break; // TODO return BAD_VALUE?
François Gaffie2110e042015-03-24 08:41:51 +0100167 }
168 return NO_ERROR;
169}
170
171routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
172{
173 // stream to strategy mapping
174 switch (stream) {
175 case AUDIO_STREAM_VOICE_CALL:
176 case AUDIO_STREAM_BLUETOOTH_SCO:
177 return STRATEGY_PHONE;
178 case AUDIO_STREAM_RING:
179 case AUDIO_STREAM_ALARM:
180 return STRATEGY_SONIFICATION;
181 case AUDIO_STREAM_NOTIFICATION:
182 return STRATEGY_SONIFICATION_RESPECTFUL;
183 case AUDIO_STREAM_DTMF:
184 return STRATEGY_DTMF;
185 default:
186 ALOGE("unknown stream type %d", stream);
187 case AUDIO_STREAM_SYSTEM:
188 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
189 // while key clicks are played produces a poor result
190 case AUDIO_STREAM_MUSIC:
191 return STRATEGY_MEDIA;
192 case AUDIO_STREAM_ENFORCED_AUDIBLE:
193 return STRATEGY_ENFORCED_AUDIBLE;
194 case AUDIO_STREAM_TTS:
195 return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
196 case AUDIO_STREAM_ACCESSIBILITY:
197 return STRATEGY_ACCESSIBILITY;
198 case AUDIO_STREAM_REROUTING:
199 return STRATEGY_REROUTING;
200 }
201}
202
203routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
204{
François Gaffie2110e042015-03-24 08:41:51 +0100205 // usage to strategy mapping
206 switch (usage) {
207 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
François Gaffie2110e042015-03-24 08:41:51 +0100208 return STRATEGY_ACCESSIBILITY;
209
210 case AUDIO_USAGE_MEDIA:
211 case AUDIO_USAGE_GAME:
Jean-Michel Trivi36867762016-12-29 12:03:28 -0800212 case AUDIO_USAGE_ASSISTANT:
François Gaffie2110e042015-03-24 08:41:51 +0100213 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
214 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
215 return STRATEGY_MEDIA;
216
217 case AUDIO_USAGE_VOICE_COMMUNICATION:
218 return STRATEGY_PHONE;
219
220 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
221 return STRATEGY_DTMF;
222
223 case AUDIO_USAGE_ALARM:
224 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
225 return STRATEGY_SONIFICATION;
226
227 case AUDIO_USAGE_NOTIFICATION:
228 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
229 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
230 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
231 case AUDIO_USAGE_NOTIFICATION_EVENT:
232 return STRATEGY_SONIFICATION_RESPECTFUL;
233
234 case AUDIO_USAGE_UNKNOWN:
235 default:
236 return STRATEGY_MEDIA;
237 }
238}
239
240audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
241{
Eric Laurent0f928fa2016-03-21 12:06:20 -0700242 DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
243 DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
François Gaffie2110e042015-03-24 08:41:51 +0100244
Eric Laurentc75307b2015-03-17 15:29:32 -0700245 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100246
Eric Laurent0f928fa2016-03-21 12:06:20 -0700247 return getDeviceForStrategyInt(strategy, availableOutputDevices,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800248 availableInputDevices, outputs, (uint32_t)AUDIO_DEVICE_NONE);
Eric Laurent28d09f02016-03-08 10:43:05 -0800249}
250
251
Eric Laurent28d09f02016-03-08 10:43:05 -0800252audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800253 DeviceVector availableOutputDevices,
254 DeviceVector availableInputDevices,
255 const SwAudioOutputCollection &outputs,
256 uint32_t outputDeviceTypesToIgnore) const
Eric Laurent28d09f02016-03-08 10:43:05 -0800257{
François Gaffie2110e042015-03-24 08:41:51 +0100258 uint32_t device = AUDIO_DEVICE_NONE;
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800259 uint32_t availableOutputDevicesType =
260 availableOutputDevices.types() & ~outputDeviceTypesToIgnore;
François Gaffie2110e042015-03-24 08:41:51 +0100261
262 switch (strategy) {
263
264 case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
265 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100266 break;
267
268 case STRATEGY_SONIFICATION_RESPECTFUL:
269 if (isInCall()) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800270 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800271 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
272 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100273 } else {
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800274 bool media_active_locally =
275 outputs.isStreamActiveLocally(
276 AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)
277 || outputs.isStreamActiveLocally(
278 AUDIO_STREAM_ACCESSIBILITY, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY);
279 // routing is same as media without the "remote" device
280 device = getDeviceForStrategyInt(STRATEGY_MEDIA,
281 availableOutputDevices,
282 availableInputDevices, outputs,
283 AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore);
284 // if no media is playing on the device, check for mandatory use of "safe" speaker
285 // when media would have played on speaker, and the safe speaker path is available
286 if (!media_active_locally
287 && (device & AUDIO_DEVICE_OUT_SPEAKER)
288 && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
Eric Laurent9a7d9222015-07-02 15:30:23 -0700289 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
290 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
291 }
François Gaffie2110e042015-03-24 08:41:51 +0100292 }
293 break;
294
295 case STRATEGY_DTMF:
296 if (!isInCall()) {
297 // when off call, DTMF strategy follows the same rules as MEDIA strategy
Eric Laurent28d09f02016-03-08 10:43:05 -0800298 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800299 STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs,
300 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100301 break;
302 }
303 // when in call, DTMF and PHONE strategies follow the same rules
304 // FALL THROUGH
305
306 case STRATEGY_PHONE:
307 // Force use of only devices on primary output if:
308 // - in call AND
309 // - cannot route from voice call RX OR
310 // - audio HAL version is < 3.0 and TX device is on the primary HW module
311 if (getPhoneState() == AUDIO_MODE_IN_CALL) {
312 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
313 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
314 audio_devices_t availPrimaryInputDevices =
315 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
Eric Laurent58a73fc2018-02-21 18:46:13 -0800316
317 // TODO: getPrimaryOutput return only devices from first module in
318 // audio_policy_configuration.xml, hearing aid is not there, but it's
319 // a primary device
320 // FIXME: this is not the right way of solving this problem
François Gaffie2110e042015-03-24 08:41:51 +0100321 audio_devices_t availPrimaryOutputDevices =
Eric Laurent58a73fc2018-02-21 18:46:13 -0800322 (primaryOutput->supportedDevices() | AUDIO_DEVICE_OUT_HEARING_AID) &
323 availableOutputDevices.types();
François Gaffie2110e042015-03-24 08:41:51 +0100324
325 if (((availableInputDevices.types() &
326 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
327 (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -0700328 (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
François Gaffie2110e042015-03-24 08:41:51 +0100329 availableOutputDevicesType = availPrimaryOutputDevices;
330 }
331 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800332 // for phone strategy, we first consider the forced use and then the available devices by
333 // order of priority
François Gaffie2110e042015-03-24 08:41:51 +0100334 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
335 case AUDIO_POLICY_FORCE_BT_SCO:
336 if (!isInCall() || strategy != STRATEGY_DTMF) {
337 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
338 if (device) break;
339 }
340 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
341 if (device) break;
342 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
343 if (device) break;
344 // if SCO device is requested but no SCO device is available, fall back to default case
345 // FALL THROUGH
346
347 default: // FORCE_NONE
Eric Laurent58a73fc2018-02-21 18:46:13 -0800348 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
349 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100350 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
351 if (!isInCall() &&
352 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800353 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100354 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
355 if (device) break;
356 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
357 if (device) break;
358 }
359 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
360 if (device) break;
361 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
362 if (device) break;
Eric Laurenta0b18ce2016-03-08 11:05:00 -0800363 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
364 if (device) break;
Eric Laurent904d6322017-03-17 17:20:47 -0700365 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
366 if (device) break;
François Gaffie2110e042015-03-24 08:41:51 +0100367 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
368 if (device) break;
369 if (!isInCall()) {
370 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
371 if (device) break;
372 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
373 if (device) break;
374 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
375 if (device) break;
376 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
377 if (device) break;
378 }
379 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
François Gaffie2110e042015-03-24 08:41:51 +0100380 break;
381
382 case AUDIO_POLICY_FORCE_SPEAKER:
383 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
384 // A2DP speaker when forcing to speaker output
385 if (!isInCall() &&
386 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800387 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100388 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
389 if (device) break;
390 }
391 if (!isInCall()) {
392 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
393 if (device) break;
394 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
395 if (device) break;
396 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
397 if (device) break;
398 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
399 if (device) break;
400 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
401 if (device) break;
402 }
François Gaffie2110e042015-03-24 08:41:51 +0100403 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100404 break;
405 }
406 break;
407
408 case STRATEGY_SONIFICATION:
409
410 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
411 // handleIncallSonification().
412 if (isInCall()) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800413 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800414 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
415 outputDeviceTypesToIgnore);
François Gaffie2110e042015-03-24 08:41:51 +0100416 break;
417 }
418 // FALL THROUGH
419
420 case STRATEGY_ENFORCED_AUDIBLE:
421 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
422 // except:
423 // - when in call where it doesn't default to STRATEGY_PHONE behavior
424 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
425
426 if ((strategy == STRATEGY_SONIFICATION) ||
427 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
428 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
François Gaffie2110e042015-03-24 08:41:51 +0100429 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800430
431 // if SCO headset is connected and we are told to use it, play ringtone over
432 // speaker and BT SCO
Jack He96117ae2018-02-12 20:52:53 -0800433 if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) {
Eric Laurenta8e0f022017-01-27 17:41:53 -0800434 uint32_t device2 = AUDIO_DEVICE_NONE;
435 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
436 if (device2 == AUDIO_DEVICE_NONE) {
437 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
438 }
439 if (device2 == AUDIO_DEVICE_NONE) {
440 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
441 }
Jack He96117ae2018-02-12 20:52:53 -0800442 // Use ONLY Bluetooth SCO output when ringing in vibration mode
443 if (!((mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
444 && (strategy == STRATEGY_ENFORCED_AUDIBLE))) {
445 if (mForceUse[AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING]
446 == AUDIO_POLICY_FORCE_BT_SCO) {
447 if (device2 != AUDIO_DEVICE_NONE) {
448 device = device2;
449 break;
450 }
451 }
452 }
453 // Use both Bluetooth SCO and phone default output when ringing in normal mode
454 if (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) {
455 if (device2 != AUDIO_DEVICE_NONE) {
456 device |= device2;
457 break;
458 }
Eric Laurenta8e0f022017-01-27 17:41:53 -0800459 }
460 }
François Gaffie2110e042015-03-24 08:41:51 +0100461 // The second device used for sonification is the same as the device used by media strategy
462 // FALL THROUGH
463
François Gaffie2110e042015-03-24 08:41:51 +0100464 case STRATEGY_ACCESSIBILITY:
465 if (strategy == STRATEGY_ACCESSIBILITY) {
466 // do not route accessibility prompts to a digital output currently configured with a
467 // compressed format as they would likely not be mixed and dropped.
468 for (size_t i = 0; i < outputs.size(); i++) {
469 sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
470 audio_devices_t devices = desc->device() &
471 (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
472 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
473 devices != AUDIO_DEVICE_NONE) {
474 availableOutputDevicesType = availableOutputDevices.types() & ~devices;
475 }
476 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800477 availableOutputDevices =
478 availableOutputDevices.getDevicesFromType(availableOutputDevicesType);
479 if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
480 outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
481 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800482 STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
483 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800484 }
485 if (isInCall()) {
486 return getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800487 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
488 outputDeviceTypesToIgnore);
Eric Laurent28d09f02016-03-08 10:43:05 -0800489 }
François Gaffie2110e042015-03-24 08:41:51 +0100490 }
Eric Laurent28d09f02016-03-08 10:43:05 -0800491 // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA
François Gaffie2110e042015-03-24 08:41:51 +0100492 // FALL THROUGH
493
Eric Laurent28d09f02016-03-08 10:43:05 -0800494 // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now
François Gaffie2110e042015-03-24 08:41:51 +0100495 case STRATEGY_REROUTING:
496 case STRATEGY_MEDIA: {
497 uint32_t device2 = AUDIO_DEVICE_NONE;
498 if (strategy != STRATEGY_SONIFICATION) {
499 // no sonification on remote submix (e.g. WFD)
Eric Laurent28d09f02016-03-08 10:43:05 -0800500 if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
501 String8("0")) != 0) {
François Gaffie2110e042015-03-24 08:41:51 +0100502 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
503 }
504 }
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700505 if (isInCall() && (strategy == STRATEGY_MEDIA)) {
Eric Laurent28d09f02016-03-08 10:43:05 -0800506 device = getDeviceForStrategyInt(
Jean-Michel Trivi61309522018-01-23 09:58:17 -0800507 STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
508 outputDeviceTypesToIgnore);
Eric Laurenta20d4fa2015-06-04 18:39:28 -0700509 break;
510 }
Eric Laurent58a73fc2018-02-21 18:46:13 -0800511 if (device2 == AUDIO_DEVICE_NONE) {
512 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID;
513 }
François Gaffie2110e042015-03-24 08:41:51 +0100514 if ((device2 == AUDIO_DEVICE_NONE) &&
515 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Aniket Kumar Lataa8ee9962018-01-31 20:24:23 -0800516 outputs.isA2dpSupported()) {
François Gaffie2110e042015-03-24 08:41:51 +0100517 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
518 if (device2 == AUDIO_DEVICE_NONE) {
519 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
520 }
521 if (device2 == AUDIO_DEVICE_NONE) {
522 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
523 }
524 }
525 if ((device2 == AUDIO_DEVICE_NONE) &&
526 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
527 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
528 }
529 if (device2 == AUDIO_DEVICE_NONE) {
530 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
531 }
Jean-Michel Trivi5c233f82015-04-03 09:21:24 -0700532 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100533 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
534 }
535 if (device2 == AUDIO_DEVICE_NONE) {
536 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
537 }
538 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent904d6322017-03-17 17:20:47 -0700539 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET;
540 }
541 if (device2 == AUDIO_DEVICE_NONE) {
François Gaffie2110e042015-03-24 08:41:51 +0100542 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
543 }
544 if (device2 == AUDIO_DEVICE_NONE) {
545 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
546 }
547 if (device2 == AUDIO_DEVICE_NONE) {
548 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
549 }
550 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
551 // no sonification on aux digital (e.g. HDMI)
552 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
553 }
554 if ((device2 == AUDIO_DEVICE_NONE) &&
555 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
556 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
557 }
558 if (device2 == AUDIO_DEVICE_NONE) {
559 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
560 }
561 int device3 = AUDIO_DEVICE_NONE;
562 if (strategy == STRATEGY_MEDIA) {
563 // ARC, SPDIF and AUX_LINE can co-exist with others.
564 device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
565 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
566 device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
567 }
568
569 device2 |= device3;
570 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
571 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
572 device |= device2;
573
574 // If hdmi system audio mode is on, remove speaker out of output list.
575 if ((strategy == STRATEGY_MEDIA) &&
576 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
577 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
578 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
579 }
Jean-Michel Trivi654afa02017-05-11 14:12:33 -0700580
581 // for STRATEGY_SONIFICATION:
582 // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead
583 if ((strategy == STRATEGY_SONIFICATION) &&
584 (device & AUDIO_DEVICE_OUT_SPEAKER) &&
585 (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) {
586 device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE;
587 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
588 }
François Gaffie2110e042015-03-24 08:41:51 +0100589 } break;
590
591 default:
592 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
593 break;
594 }
595
Eric Laurent5a2b6292016-04-14 18:05:57 -0700596 if (device == AUDIO_DEVICE_NONE) {
597 ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy);
598 device = mApmObserver->getDefaultOutputDevice()->type();
599 ALOGE_IF(device == AUDIO_DEVICE_NONE,
600 "getDeviceForStrategy() no default device defined");
601 }
François Gaffie2110e042015-03-24 08:41:51 +0100602 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
603 return device;
604}
605
606
607audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
608{
609 const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
610 const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
Eric Laurentc75307b2015-03-17 15:29:32 -0700611 const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100612 audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
613
614 uint32_t device = AUDIO_DEVICE_NONE;
615
616 switch (inputSource) {
617 case AUDIO_SOURCE_VOICE_UPLINK:
618 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
619 device = AUDIO_DEVICE_IN_VOICE_CALL;
620 break;
621 }
622 break;
623
624 case AUDIO_SOURCE_DEFAULT:
625 case AUDIO_SOURCE_MIC:
626 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
627 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
628 } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
629 (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
630 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
631 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
632 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700633 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
634 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100635 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
636 device = AUDIO_DEVICE_IN_USB_DEVICE;
637 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
638 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
639 }
640 break;
641
642 case AUDIO_SOURCE_VOICE_COMMUNICATION:
643 // Allow only use of devices on primary input if in call and HAL does not support routing
644 // to voice call path.
645 if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
646 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
647 sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
648 availableDeviceTypes =
649 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
650 & ~AUDIO_DEVICE_BIT_IN;
651 }
652
653 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
654 case AUDIO_POLICY_FORCE_BT_SCO:
655 // if SCO device is requested but no SCO device is available, fall back to default case
656 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
657 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
658 break;
659 }
660 // FALL THROUGH
661
662 default: // FORCE_NONE
663 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
664 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700665 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
666 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100667 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
668 device = AUDIO_DEVICE_IN_USB_DEVICE;
669 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
670 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
671 }
672 break;
673
674 case AUDIO_POLICY_FORCE_SPEAKER:
675 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
676 device = AUDIO_DEVICE_IN_BACK_MIC;
677 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
678 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
679 }
680 break;
681 }
682 break;
683
684 case AUDIO_SOURCE_VOICE_RECOGNITION:
rago8a397d52015-12-02 11:27:57 -0800685 case AUDIO_SOURCE_UNPROCESSED:
François Gaffie2110e042015-03-24 08:41:51 +0100686 case AUDIO_SOURCE_HOTWORD:
687 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
688 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
689 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
690 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
691 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurent904d6322017-03-17 17:20:47 -0700692 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) {
693 device = AUDIO_DEVICE_IN_USB_HEADSET;
François Gaffie2110e042015-03-24 08:41:51 +0100694 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
695 device = AUDIO_DEVICE_IN_USB_DEVICE;
696 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
697 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
698 }
699 break;
700 case AUDIO_SOURCE_CAMCORDER:
701 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
702 device = AUDIO_DEVICE_IN_BACK_MIC;
703 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
704 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
705 }
706 break;
707 case AUDIO_SOURCE_VOICE_DOWNLINK:
708 case AUDIO_SOURCE_VOICE_CALL:
709 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
710 device = AUDIO_DEVICE_IN_VOICE_CALL;
711 }
712 break;
713 case AUDIO_SOURCE_REMOTE_SUBMIX:
714 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
715 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
716 }
717 break;
718 case AUDIO_SOURCE_FM_TUNER:
719 if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
720 device = AUDIO_DEVICE_IN_FM_TUNER;
721 }
722 break;
723 default:
724 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
725 break;
726 }
Eric Laurent5a2b6292016-04-14 18:05:57 -0700727 if (device == AUDIO_DEVICE_NONE) {
728 ALOGV("getDeviceForInputSource() no device found for source %d", inputSource);
729 if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) {
730 device = AUDIO_DEVICE_IN_STUB;
731 }
732 ALOGE_IF(device == AUDIO_DEVICE_NONE,
733 "getDeviceForInputSource() no default device defined");
734 }
François Gaffie2110e042015-03-24 08:41:51 +0100735 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
736 return device;
737}
738
739template <>
740AudioPolicyManagerInterface *Engine::queryInterface()
741{
742 return &mManagerInterface;
743}
744
745} // namespace audio_policy
746} // namespace android
747
748