blob: 8093e12652603c29475844213486cb206fe4066b [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
Mingming Yinfddaa942012-12-27 17:42:46 -08003 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Iliyan Malchev4765c432012-06-11 14:36:16 -07004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
Ajay Dudani9746c472012-06-18 16:01:16 -070018#define LOG_TAG "AudioPolicyManagerALSA"
Iliyan Malchev4765c432012-06-11 14:36:16 -070019//#define LOG_NDEBUG 0
Mingming Yinbbd94ad2012-11-29 20:04:36 -080020//#define LOG_NDDEBUG 0
Iliyan Malchev4113f342012-06-11 14:39:47 -070021
Mingming Yinbbd94ad2012-11-29 20:04:36 -080022//#define VERY_VERBOSE_LOGGING
23#ifdef VERY_VERBOSE_LOGGING
24#define ALOGVV ALOGV
25#else
26#define ALOGVV(a...) do { } while(0)
27#endif
28
29// A device mask for all audio input devices that are considered "virtual" when evaluating
30// active inputs in getActiveInput()
31#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX
32
33#include <utils/Log.h>
Mingming Yin979666c2012-12-09 23:22:36 -080034
Iliyan Malchev4765c432012-06-11 14:36:16 -070035#include "AudioPolicyManagerALSA.h"
Mingming Yinbbd94ad2012-11-29 20:04:36 -080036#include <hardware/audio_effect.h>
37#include <hardware/audio.h>
38#include <hardware_legacy/audio_policy_conf.h>
39#include <math.h>
Iliyan Malchev4765c432012-06-11 14:36:16 -070040#include <media/mediarecorder.h>
Mingming Yinbbd94ad2012-11-29 20:04:36 -080041#include <stdio.h>
Mingming Yin9b79f6d2013-01-09 15:43:18 -080042#include <cutils/properties.h>
Mingming Yinbbd94ad2012-11-29 20:04:36 -080043
Iliyan Malchev4765c432012-06-11 14:36:16 -070044namespace android_audio_legacy {
45
46// ----------------------------------------------------------------------------
Iliyan Malchev4765c432012-06-11 14:36:16 -070047// AudioPolicyManagerALSA
48// ----------------------------------------------------------------------------
49
Mingming Yinbbd94ad2012-11-29 20:04:36 -080050AudioParameter param;
Ajay Dudani9746c472012-06-18 16:01:16 -070051
Srikanth Kattaf2a261f2013-05-15 17:47:11 +053052void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
53 bool on,
54 audio_io_handle_t output,
55 int delayMs,
56 audio_devices_t device)
57{
58 ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
59 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
60 if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
61 setStreamMute(stream, on, output, delayMs, device);
62 }
63 }
64}
Yamit Mehta2b0e59b2013-04-05 17:07:33 +053065
66uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
67 audio_devices_t prevDevice,
68 uint32_t delayMs)
69{
70 // mute/unmute strategies using an incompatible device combination
71 // if muting, wait for the audio in pcm buffer to be drained before proceeding
72 // if unmuting, unmute only after the specified delay
73 if (outputDesc->isDuplicated()) {
74 return 0;
75 }
76
77 uint32_t muteWaitMs = 0;
78 audio_devices_t device = outputDesc->device();
79 bool shouldMute = (outputDesc->refCount() != 0) &&
80 (AudioSystem::popCount(device) >= 2);
81 // temporary mute output if device selection changes to avoid volume bursts due to
82 // different per device volumes
83 bool tempMute = (outputDesc->refCount() != 0) && (device != prevDevice);
84
85 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
86 audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
87 bool mute = shouldMute && (curDevice & device) && (curDevice != device);
88 bool doMute = false;
89
90 if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
91 doMute = true;
92 outputDesc->mStrategyMutedByDevice[i] = true;
93 } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
94 doMute = true;
95 outputDesc->mStrategyMutedByDevice[i] = false;
96 }
97 if (doMute || tempMute) {
98 for (size_t j = 0; j < mOutputs.size(); j++) {
99 AudioOutputDescriptor *desc = mOutputs.valueAt(j);
100 if ((desc->supportedDevices() & outputDesc->supportedDevices())
101 == AUDIO_DEVICE_NONE) {
102 continue;
103 }
104 audio_io_handle_t curOutput = mOutputs.keyAt(j);
105 ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
106 mute ? "muting" : "unmuting", i, curDevice, curOutput);
107 setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs * 4);
108 if (desc->strategyRefCount((routing_strategy)i) != 0) {
109 if (tempMute) {
Chaithanya Krishna Bacharajua95a0e42013-06-13 09:48:43 +0530110 if ((desc != outputDesc) && (desc->device() == device)) {
111 ALOGD("avoid tempmute on curOutput %d as device is same", curOutput);
112 } else {
113 setStrategyMute((routing_strategy)i, true, curOutput);
Naresh Tannirua222c362013-06-27 19:46:37 +0530114
115 //Change latency for tunnel/LPA player to make sure no noise on device switch
116 //Routing to BTA2DP, USB device , Proxy(WFD) will take time, increasing latency time
117 if((desc->mFlags & AUDIO_OUTPUT_FLAG_LPA) || (desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL)
118 || (device & AUDIO_DEVICE_OUT_USB_DEVICE) || (device & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)
Vivek Singhe64d3832013-07-05 12:09:18 +0530119 || (device & AUDIO_DEVICE_OUT_PROXY) || (device & AUDIO_DEVICE_OUT_FM))
Naresh Tannirua222c362013-06-27 19:46:37 +0530120 {
121 setStrategyMute((routing_strategy)i, false, curOutput,desc->latency()*4 ,device);
122 }
123 else
124 setStrategyMute((routing_strategy)i, false, curOutput,desc->latency()*2 ,device);
Chaithanya Krishna Bacharajua95a0e42013-06-13 09:48:43 +0530125 }
Yamit Mehta2b0e59b2013-04-05 17:07:33 +0530126 }
127 if (tempMute || mute) {
128 if (muteWaitMs < desc->latency()) {
129 muteWaitMs = desc->latency();
130 }
131 }
132 }
133 }
134 }
135 }
136
137 // FIXME: should not need to double latency if volume could be applied immediately by the
138 // audioflinger mixer. We must account for the delay between now and the next time
139 // the audioflinger thread for this output will process a buffer (which corresponds to
140 // one buffer size, usually 1/2 or 1/4 of the latency).
141 muteWaitMs *= 2;
142 // wait for the PCM output buffers to empty before proceeding with the rest of the command
143 if (muteWaitMs > delayMs) {
144 muteWaitMs -= delayMs;
145 usleep(muteWaitMs * 1000);
146 return muteWaitMs;
147 }
148 return 0;
149}
150
Srikanth Kattaf2a261f2013-05-15 17:47:11 +0530151void AudioPolicyManager::setStreamMute(int stream,
152 bool on,
153 audio_io_handle_t output,
154 int delayMs,
155 audio_devices_t device)
156{
157 StreamDescriptor &streamDesc = mStreams[stream];
158 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
159 if (device == AUDIO_DEVICE_NONE) {
160 device = outputDesc->device();
161 }
162
163 ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
164 stream, on, output, outputDesc->mMuteCount[stream], device);
165
166 if (on) {
167 if (outputDesc->mMuteCount[stream] > 0) {
168 ALOGV("setStreamMute() muting already muted stream!");
169 return;
170 }
171 if (outputDesc->mMuteCount[stream] == 0) {
172 if (streamDesc.mCanBeMuted &&
173 ((stream != AudioSystem::ENFORCED_AUDIBLE) ||
174 (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_NONE))) {
175 checkAndSetVolume(stream, 0, output, device, delayMs);
176 }
177 }
178 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
179 outputDesc->mMuteCount[stream]++;
180 } else {
181 if (outputDesc->mMuteCount[stream] == 0) {
182 ALOGV("setStreamMute() unmuting non muted stream!");
183 return;
184 }
185 if (--outputDesc->mMuteCount[stream] == 0) {
186 checkAndSetVolume(stream,
187 streamDesc.getVolumeIndex(device),
188 output,
189 device,
190 delayMs);
191 }
192 }
193}
194
Yamit Mehta2b0e59b2013-04-05 17:07:33 +0530195
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800196status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
197 AudioSystem::device_connection_state state,
198 const char *device_address)
199{
200 SortedVector <audio_io_handle_t> outputs;
201
202 ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
203
204 // connect/disconnect only 1 device at a time
205 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
206
207 if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
208 ALOGE("setDeviceConnectionState() invalid address: %s", device_address);
209 return BAD_VALUE;
210 }
211
212 // handle output devices
213 if (audio_is_output_device(device)) {
214
Mingming Yin979666c2012-12-09 23:22:36 -0800215 //Use QCOM's a2dp and usb audio solution, no need to check here
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800216 /*if (!mHasA2dp && audio_is_a2dp_device(device)) {
217 ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device);
218 return BAD_VALUE;
Mingming Yin979666c2012-12-09 23:22:36 -0800219 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800220 if (!mHasUsb && audio_is_usb_device(device)) {
221 ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device);
222 return BAD_VALUE;
Mingming Yin979666c2012-12-09 23:22:36 -0800223 }*/
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800224 if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) {
225 ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device);
226 return BAD_VALUE;
227 }
228
229 // save a copy of the opened output descriptors before any output is opened or closed
230 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
231 mPreviousOutputs = mOutputs;
232 switch (state)
233 {
234 // handle output device connection
235 case AudioSystem::DEVICE_STATE_AVAILABLE:
236 if (mAvailableOutputDevices & device) {
237 ALOGW("setDeviceConnectionState() device already connected: %x", device);
238 return INVALID_OPERATION;
239 }
240 ALOGV("setDeviceConnectionState() connecting device %x", device);
241
242 if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
243 return INVALID_OPERATION;
244 }
245 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs",
246 outputs.size());
247 // register new device as available
248 mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device);
249
250 if (audio_is_a2dp_device(device)) {
251 AudioParameter param;
252 param.add(String8("a2dp_connected"), String8("true"));
253 mpClientInterface->setParameters(0, param.toString());
254 }
Mingming Yin979666c2012-12-09 23:22:36 -0800255 if ( audio_is_usb_device(device)) {
256 AudioParameter param;
257 param.add(String8("usb_connected"), String8("true"));
258 mpClientInterface->setParameters(0, param.toString());
259 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800260 if (!outputs.isEmpty()) {
261 String8 paramStr;
262 if (audio_is_a2dp_device(device)) {
263 // handle A2DP device connection
264 AudioParameter param;
265 param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address));
266 paramStr = param.toString();
267 mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
268 mA2dpSuspended = false;
269 } else if (audio_is_bluetooth_sco_device(device)) {
270 // handle SCO device connection
271 mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
Mingming Yin979666c2012-12-09 23:22:36 -0800272 } else if (audio_is_usb_device(device)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800273 // handle USB device connection
274 mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
275 paramStr = mUsbCardAndDevice;
276 }
277 // not currently handling multiple simultaneous submixes: ignoring remote submix
278 // case and address
279 if (!paramStr.isEmpty()) {
280 for (size_t i = 0; i < outputs.size(); i++) {
281 mpClientInterface->setParameters(outputs[i], paramStr);
282 }
283 }
284 }
285 break;
286 // handle output device disconnection
287 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
288 if (!(mAvailableOutputDevices & device)) {
289 ALOGW("setDeviceConnectionState() device not connected: %x", device);
290 return INVALID_OPERATION;
291 }
292
293 ALOGV("setDeviceConnectionState() disconnecting device %x", device);
294 // remove device from available output devices
295 mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device);
296
297 checkOutputsForDevice(device, state, outputs);
298 if (audio_is_a2dp_device(device)) {
299 // handle A2DP device disconnection
300 mA2dpDeviceAddress = "";
301 mA2dpSuspended = false;
302
303 AudioParameter param;
304 param.add(String8("a2dp_connected"), String8("false"));
305 mpClientInterface->setParameters(0, param.toString());
306
307 } else if (audio_is_bluetooth_sco_device(device)) {
308 // handle SCO device disconnection
309 mScoDeviceAddress = "";
Mingming Yin979666c2012-12-09 23:22:36 -0800310 } else if (audio_is_usb_device(device)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800311 // handle USB device disconnection
312 mUsbCardAndDevice = "";
Mingming Yin979666c2012-12-09 23:22:36 -0800313
314 AudioParameter param;
315 param.add(String8("usb_connected"), String8("false"));
316 mpClientInterface->setParameters(0, param.toString());
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800317 }
318 // not currently handling multiple simultaneous submixes: ignoring remote submix
319 // case and address
320 } break;
321
322 default:
323 ALOGE("setDeviceConnectionState() invalid state: %x", state);
324 return BAD_VALUE;
325 }
326
327 checkA2dpSuspend();
328 checkOutputForAllStrategies();
329 // outputs must be closed after checkOutputForAllStrategies() is executed
330 if (!outputs.isEmpty()) {
331 for (size_t i = 0; i < outputs.size(); i++) {
332 // close unused outputs after device disconnection or direct outputs that have been
333 // opened by checkOutputsForDevice() to query dynamic parameters
Vidyakumar Athota27598212012-12-27 15:15:42 -0800334 if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800335 closeOutput(outputs[i]);
336 }
337 }
338 }
339
340 updateDevicesAndOutputs();
341#ifdef QCOM_PROXY_DEVICE_ENABLED
342 if (state == AudioSystem::DEVICE_STATE_AVAILABLE &&
Mingming Yin979666c2012-12-09 23:22:36 -0800343 audio_is_a2dp_device(device) &&
344 (mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800345 ALOGV("Delay the proxy device open");
346 return NO_ERROR;
347 }
348#endif
349
Mingming Yin979666c2012-12-09 23:22:36 -0800350 audio_devices_t newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
Mingming Yin9b79f6d2013-01-09 15:43:18 -0800351#ifdef QCOM_FM_ENABLED
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800352 if(device == AUDIO_DEVICE_OUT_FM) {
353 if (state == AudioSystem::DEVICE_STATE_AVAILABLE) {
354 ALOGV("setDeviceConnectionState() changeRefCount Inc");
355 mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, 1);
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -0700356 newDevice = (audio_devices_t)(AudioPolicyManagerBase::getNewDevice(mPrimaryOutput, false) | AUDIO_DEVICE_OUT_FM);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800357 }
358 else {
359 ALOGV("setDeviceConnectionState() changeRefCount Dec");
360 mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::FM, -1);
361 }
Krishnankutty Kolathappilly58c98932013-03-18 23:45:04 -0700362
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800363 AudioParameter param = AudioParameter();
364 param.addInt(String8(AudioParameter::keyHandleFm), (int)newDevice);
365 ALOGV("setDeviceConnectionState() setParameters handle_fm");
366 mpClientInterface->setParameters(mPrimaryOutput, param.toString());
367 }
368#endif
Preetam Singh Ranawat9f997d42013-06-10 22:05:40 +0530369 for (int i = mOutputs.size() -1; i >= 0; i--) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800370 audio_devices_t newDevice = getNewDevice(mOutputs.keyAt(i), true /*fromCache*/);
Mingming Yin9b79f6d2013-01-09 15:43:18 -0800371#ifdef QCOM_ANC_HEADSET_ENABLED
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800372 if(device == AUDIO_DEVICE_OUT_ANC_HEADPHONE ||
373 device == AUDIO_DEVICE_OUT_ANC_HEADSET) {
374 if(newDevice == 0){
375 newDevice = getDeviceForStrategy(STRATEGY_MEDIA, false);
376 }
377 }
378#endif
379 setOutputDevice(mOutputs.keyAt(i),
380 getNewDevice(mOutputs.keyAt(i), true /*fromCache*/),
381 true,
382 0);
383 }
384
385 if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) {
386 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
387 } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
388 device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
389 device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
390 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
391 } else if(device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET){
392 device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
393#ifdef QCOM_ANC_HEADSET_ENABLED
394 } else if(device == AUDIO_DEVICE_OUT_ANC_HEADSET){
395 device = AUDIO_DEVICE_IN_ANC_HEADSET; //wait for actual ANC device
396#endif
397 } else {
398 return NO_ERROR;
399 }
400 }
401 // handle input devices
402 if (audio_is_input_device(device)) {
403
404 switch (state)
405 {
406 // handle input device connection
407 case AudioSystem::DEVICE_STATE_AVAILABLE: {
408 if (mAvailableInputDevices & device) {
409 ALOGW("setDeviceConnectionState() device already connected: %d", device);
410 return INVALID_OPERATION;
411 }
412 mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN);
413 }
414 break;
415
416 // handle input device disconnection
417 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
418 if (!(mAvailableInputDevices & device)) {
419 ALOGW("setDeviceConnectionState() device not connected: %d", device);
420 return INVALID_OPERATION;
421 }
422 mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device);
423 } break;
424
425 default:
426 ALOGE("setDeviceConnectionState() invalid state: %x", state);
427 return BAD_VALUE;
428 }
429
430 audio_io_handle_t activeInput = getActiveInput();
431 if (activeInput != 0) {
432 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
433 audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
434 if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
435 ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
436 inputDesc->mDevice, newDevice, activeInput);
437 inputDesc->mDevice = newDevice;
438 AudioParameter param = AudioParameter();
439 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
440 mpClientInterface->setParameters(activeInput, param.toString());
441 }
442 }
443
444 return NO_ERROR;
445 }
446
447 ALOGW("setDeviceConnectionState() invalid device: %x", device);
448 return BAD_VALUE;
449}
450
451
452AudioSystem::device_connection_state AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
453 const char *device_address)
454{
455 AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
456 String8 address = String8(device_address);
457 if (audio_is_output_device(device)) {
458 if (device & mAvailableOutputDevices) {
459 if (audio_is_a2dp_device(device) &&
Mingming Yin979666c2012-12-09 23:22:36 -0800460 ((address != "" && mA2dpDeviceAddress != address))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800461 return state;
462 }
463 if (audio_is_bluetooth_sco_device(device) &&
464 address != "" && mScoDeviceAddress != address) {
465 return state;
466 }
467 if (audio_is_usb_device(device) &&
Mingming Yin979666c2012-12-09 23:22:36 -0800468 ((address != "" && mUsbCardAndDevice != address))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800469 ALOGE("getDeviceConnectionState() invalid device: %x", device);
470 return state;
471 }
472 if (audio_is_remote_submix_device((audio_devices_t)device) && !mHasRemoteSubmix) {
473 return state;
474 }
475 state = AudioSystem::DEVICE_STATE_AVAILABLE;
476 }
477 } else if (audio_is_input_device(device)) {
478 if (device & mAvailableInputDevices) {
479 state = AudioSystem::DEVICE_STATE_AVAILABLE;
480 }
481 }
482
483 return state;
484}
485
486
487void AudioPolicyManager::setPhoneState(int state)
488{
489 ALOGV("setPhoneState() state %d", state);
490 audio_devices_t newDevice = AUDIO_DEVICE_NONE;
491 if (state < 0 || state >= AudioSystem::NUM_MODES) {
492 ALOGW("setPhoneState() invalid state %d", state);
493 return;
494 }
495
496 if (state == mPhoneState ) {
497 ALOGW("setPhoneState() setting same state %d", state);
498 return;
499 }
500
501 // if leaving call state, handle special case of active streams
502 // pertaining to sonification strategy see handleIncallSonification()
503 if (isInCall()) {
504 ALOGV("setPhoneState() in call state management: new state is %d", state);
505 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
506 handleIncallSonification(stream, false, true);
507 }
508 }
509
510 // store previous phone state for management of sonification strategy below
511 int oldState = mPhoneState;
512 mPhoneState = state;
513 bool force = false;
514
515 // are we entering or starting a call
516 if (!isStateInCall(oldState) && isStateInCall(state)) {
517 ALOGV(" Entering call in setPhoneState()");
518 // force routing command to audio hardware when starting a call
519 // even if no device change is needed
520 force = true;
521 } else if (isStateInCall(oldState) && !isStateInCall(state)) {
522 ALOGV(" Exiting call in setPhoneState()");
523 // force routing command to audio hardware when exiting a call
524 // even if no device change is needed
525 force = true;
526 } else if (isStateInCall(state) && (state != oldState)) {
527 ALOGV(" Switching between telephony and VoIP in setPhoneState()");
528 // force routing command to audio hardware when switching between telephony and VoIP
529 // even if no device change is needed
530 force = true;
531 }
532
533 // check for device and output changes triggered by new phone state
534 // Need to update A2DP suspend first then getNewDevice(from cache)
535 checkA2dpSuspend();
536 checkOutputForAllStrategies();
537 updateDevicesAndOutputs();
538 newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
539
540 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
541
542 // force routing command to audio hardware when ending call
543 // even if no device change is needed
544 if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
545 newDevice = hwOutputDesc->device();
546 }
547
548 // when changing from ring tone to in call mode, mute the ringing tone
549 // immediately and delay the route change to avoid sending the ring tone
550 // tail into the earpiece or headset.
551 int delayMs = 0;
552 if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
553 // delay the device change command by twice the output latency to have some margin
554 // and be sure that audio buffers not yet affected by the mute are out when
555 // we actually apply the route change
556 delayMs = hwOutputDesc->mLatency*2;
557 setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
558 }
559
Mingming Yinb8851fa2013-01-06 20:50:34 -0800560 // Ignore the delay to enable voice call on this target as the enabling the
561 // voice call has enough delay to make sure the ringtone audio completely
562 // played out
Mingming Yin9b79f6d2013-01-09 15:43:18 -0800563 if (state == AUDIO_MODE_IN_CALL &&
564#ifdef QCOM_CSDCLIENT_ENABLED
565 platform_is_Fusion3() &&
566#endif
567 oldState == AUDIO_MODE_RINGTONE) {
Mingming Yinb8851fa2013-01-06 20:50:34 -0800568 delayMs = 40;
569 }
570
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800571 if (isStateInCall(state)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800572 for (size_t i = 0; i < mOutputs.size(); i++) {
573 AudioOutputDescriptor *desc = mOutputs.valueAt(i);
574 //take the biggest latency for all outputs
575 if (delayMs < desc->mLatency*2) {
576 delayMs = desc->mLatency*2;
577 }
578 //mute STRATEGY_MEDIA on all outputs
579 if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
580 setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
581 setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
582 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
583 }
584 }
585 }
586
587 // change routing is necessary
Mingming Yin40ae5872013-04-12 16:19:34 -0700588 setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
589
590 //update device for all non-primary outputs
Mingming Yin7955ffc2013-01-23 21:07:27 -0800591 for (size_t i = 0; i < mOutputs.size(); i++) {
592 audio_io_handle_t output = mOutputs.keyAt(i);
Mingming Yin40ae5872013-04-12 16:19:34 -0700593 if (output != mPrimaryOutput) {
594 newDevice = getNewDevice(output, false /*fromCache*/);
595 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
596 }
Mingming Yin7955ffc2013-01-23 21:07:27 -0800597 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800598
599 // if entering in call state, handle special case of active streams
600 // pertaining to sonification strategy see handleIncallSonification()
601 if (isStateInCall(state)) {
602 ALOGV("setPhoneState() in call state management: new state is %d", state);
603 // unmute the ringing tone after a sufficient delay if it was muted before
604 // setting output device above
605 if (oldState == AudioSystem::MODE_RINGTONE) {
606 setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
607 }
608 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
609 handleIncallSonification(stream, true, true);
610 }
611 }
612
613 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
614 if (state == AudioSystem::MODE_RINGTONE &&
615 isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
616 mLimitRingtoneVolume = true;
617 } else {
618 mLimitRingtoneVolume = false;
619 }
620}
621
622
623void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
624{
625 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
626
627 bool forceVolumeReeval = false;
628 switch(usage) {
629 case AudioSystem::FOR_COMMUNICATION:
630 if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
631 config != AudioSystem::FORCE_NONE) {
632 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
633 return;
634 }
635 forceVolumeReeval = true;
636 mForceUse[usage] = config;
637 break;
638 case AudioSystem::FOR_MEDIA:
639 if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
640 config != AudioSystem::FORCE_WIRED_ACCESSORY &&
641 config != AudioSystem::FORCE_ANALOG_DOCK &&
642 config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE &&
643 config != AudioSystem::FORCE_NO_BT_A2DP && config != AudioSystem::FORCE_SPEAKER) {
644 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
645 return;
646 }
647 mForceUse[usage] = config;
648 break;
649 case AudioSystem::FOR_RECORD:
650 if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
651 config != AudioSystem::FORCE_NONE) {
652 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
653 return;
654 }
655 mForceUse[usage] = config;
656 break;
657 case AudioSystem::FOR_DOCK:
658 if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
659 config != AudioSystem::FORCE_BT_DESK_DOCK &&
660 config != AudioSystem::FORCE_WIRED_ACCESSORY &&
661 config != AudioSystem::FORCE_ANALOG_DOCK &&
662 config != AudioSystem::FORCE_DIGITAL_DOCK) {
663 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
664 }
665 forceVolumeReeval = true;
666 mForceUse[usage] = config;
667 break;
668 case AudioSystem::FOR_SYSTEM:
669 if (config != AudioSystem::FORCE_NONE &&
670 config != AudioSystem::FORCE_SYSTEM_ENFORCED) {
671 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
672 }
673 forceVolumeReeval = true;
674 mForceUse[usage] = config;
675 break;
676 default:
677 ALOGW("setForceUse() invalid usage %d", usage);
678 break;
679 }
680
681 // check for device and output changes triggered by new force usage
682 checkA2dpSuspend();
683 checkOutputForAllStrategies();
684 updateDevicesAndOutputs();
Preetam Singh Ranawat9f997d42013-06-10 22:05:40 +0530685 for (int i = mOutputs.size() -1; i >= 0; i--) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800686 audio_io_handle_t output = mOutputs.keyAt(i);
687 audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/);
688 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
689 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
690 applyStreamVolumes(output, newDevice, 0, true);
691 }
692 }
693
694 audio_io_handle_t activeInput = getActiveInput();
695 if (activeInput != 0) {
696 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
697 audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
698 if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
699 ALOGV("setForceUse() changing device from %x to %x for input %d",
700 inputDesc->mDevice, newDevice, activeInput);
701 inputDesc->mDevice = newDevice;
702 AudioParameter param = AudioParameter();
703 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
704 mpClientInterface->setParameters(activeInput, param.toString());
705 }
706 }
707
708}
709
Mingming Yin979666c2012-12-09 23:22:36 -0800710audio_io_handle_t AudioPolicyManager::getOutput(AudioSystem::stream_type stream,
711 uint32_t samplingRate,
712 uint32_t format,
713 uint32_t channelMask,
714 AudioSystem::output_flags flags)
715{
716 audio_io_handle_t output = 0;
717 uint32_t latency = 0;
718 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
719 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
720 ALOGV("getOutput() stream %d, samplingRate %d, format %d, channelMask %x, flags %x",
721 stream, samplingRate, format, channelMask, flags);
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800722
Mingming Yin979666c2012-12-09 23:22:36 -0800723#ifdef AUDIO_POLICY_TEST
724 if (mCurOutput != 0) {
725 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
726 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
727
728 if (mTestOutputs[mCurOutput] == 0) {
729 ALOGV("getOutput() opening test output");
730 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
731 outputDesc->mDevice = mTestDevice;
732 outputDesc->mSamplingRate = mTestSamplingRate;
733 outputDesc->mFormat = mTestFormat;
734 outputDesc->mChannelMask = mTestChannels;
735 outputDesc->mLatency = mTestLatencyMs;
736 outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
737 outputDesc->mRefCount[stream] = 0;
738 mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
739 &outputDesc->mSamplingRate,
740 &outputDesc->mFormat,
741 &outputDesc->mChannelMask,
742 &outputDesc->mLatency,
743 outputDesc->mFlags);
744 if (mTestOutputs[mCurOutput]) {
745 AudioParameter outputCmd = AudioParameter();
746 outputCmd.addInt(String8("set_id"),mCurOutput);
747 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
748 addOutput(mTestOutputs[mCurOutput], outputDesc);
749 }
750 }
751 return mTestOutputs[mCurOutput];
752 }
753#endif //AUDIO_POLICY_TEST
754
755 IOProfile *profile = getProfileForDirectOutput(device,
756 samplingRate,
757 format,
758 channelMask,
759 (audio_output_flags_t)flags);
760
761 if (profile != NULL) {
762
763 ALOGV("getOutput() opening direct output device %x", device);
764
765 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(profile);
766 outputDesc->mDevice = device;
767 outputDesc->mSamplingRate = samplingRate;
768 outputDesc->mFormat = (audio_format_t)format;
769 outputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
770 outputDesc->mLatency = 0;
771 outputDesc->mFlags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);;
772 outputDesc->mRefCount[stream] = 0;
773 outputDesc->mStopTime[stream] = 0;
774 output = mpClientInterface->openOutput(profile->mModule->mHandle,
775 &outputDesc->mDevice,
776 &outputDesc->mSamplingRate,
777 &outputDesc->mFormat,
778 &outputDesc->mChannelMask,
779 &outputDesc->mLatency,
780 outputDesc->mFlags);
781
782 // only accept an output with the requested parameters
783 if (output == 0 ||
784 (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
785 (format != 0 && format != outputDesc->mFormat) ||
786 (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
787 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
788 "format %d %d, channelMask %04x %04x", output, samplingRate,
789 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
790 outputDesc->mChannelMask);
791 if (output != 0) {
792 mpClientInterface->closeOutput(output);
793 }
794 delete outputDesc;
795 return 0;
796 }
797 addOutput(output, outputDesc);
798 ALOGV("getOutput() returns direct output %d", output);
799 return output;
800 }
801
802 // ignoring channel mask due to downmix capability in mixer
803
804 // open a non direct output
805
806 // get which output is suitable for the specified stream. The actual routing change will happen
807 // when startOutput() will be called
808 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
809
810 output = selectOutput(outputs, flags);
811
812 ALOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d,"
813 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
814
815 ALOGV("getOutput() returns output %d", output);
816
817 return output;
818}
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800819status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
820 AudioSystem::stream_type stream,
821 int session)
822{
823 ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
824 ssize_t index = mOutputs.indexOfKey(output);
825 if (index < 0) {
826 ALOGW("startOutput() unknow output %d", output);
827 return BAD_VALUE;
828 }
829
830 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
831
832 // increment usage count for this stream on the requested output:
833 // NOTE that the usage count is the same for duplicated output and hardware output which is
834 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
835 outputDesc->changeRefCount(stream, 1);
836
837 if (outputDesc->mRefCount[stream] == 1) {
838 audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
839 routing_strategy strategy = getStrategy(stream);
840 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
841 (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
842 uint32_t waitMs = 0;
843 uint32_t muteWaitMs = 0;
844 bool force = false;
845 for (size_t i = 0; i < mOutputs.size(); i++) {
846 AudioOutputDescriptor *desc = mOutputs.valueAt(i);
847 if (desc != outputDesc) {
848 // force a device change if any other output is managed by the same hw
849 // module and has a current device selection that differs from selected device.
850 // In this case, the audio HAL must receive the new device selection so that it can
851 // change the device currently selected by the other active output.
852 if (outputDesc->sharesHwModuleWith(desc) &&
853 desc->device() != newDevice) {
854 force = true;
855 }
856 // wait for audio on other active outputs to be presented when starting
857 // a notification so that audio focus effect can propagate.
858 if (shouldWait && (desc->refCount() != 0) && (waitMs < desc->latency())) {
859 waitMs = desc->latency();
860 }
861 }
862 }
863
864#ifdef QCOM_FM_ENABLED
865 if(stream == AudioSystem::FM && output == getA2dpOutput()) {
866 muteWaitMs = setOutputDevice(output, newDevice, true);
867 } else
868#endif
869 {
870 muteWaitMs = setOutputDevice(output, newDevice, force);
871 }
872
873 // handle special case for sonification while in call
874 if (isInCall()) {
875 handleIncallSonification(stream, true, false);
876 }
877
878 // apply volume rules for current stream and device if necessary
879 checkAndSetVolume(stream,
880 mStreams[stream].getVolumeIndex(newDevice),
881 output,
882 newDevice);
883
884 // update the outputs if starting an output with a stream that can affect notification
885 // routing
886 handleNotificationRoutingForStream(stream);
887 if (waitMs > muteWaitMs) {
888 usleep((waitMs - muteWaitMs) * 2 * 1000);
889 }
Sriranjan Srikantamf71989e2013-06-18 11:18:22 +0530890 } else {
891 // handle special case for sonification while in call
892 if (isInCall()) {
893 handleIncallSonification(stream, true, false);
894 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800895 }
896 return NO_ERROR;
897}
898
899status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
900 AudioSystem::stream_type stream,
901 int session)
902{
903 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
904 ssize_t index = mOutputs.indexOfKey(output);
905 if (index < 0) {
906 ALOGW("stopOutput() unknow output %d", output);
907 return BAD_VALUE;
908 }
909
910 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
911
912 // handle special case for sonification while in call
913 if (isInCall()) {
914 handleIncallSonification(stream, false, false);
915 }
916
917 if (outputDesc->mRefCount[stream] > 0) {
918 // decrement usage count of this stream on the output
919 outputDesc->changeRefCount(stream, -1);
920 // store time at which the stream was stopped - see isStreamActive()
921 if (outputDesc->mRefCount[stream] == 0) {
922 outputDesc->mStopTime[stream] = systemTime();
Sidipotu Ashokb443bf12013-05-22 19:12:01 +0530923
924 if ((outputDesc->mRefCount[AUDIO_STREAM_RING]!= 0) && (stream == AUDIO_STREAM_VOICE_CALL)) {
925 // When AUDIO_STREAM_RING is present, Send Mute on RING
926 // if it gets stopOutput on AUDIO_STREAM_VOICE_CALL
927 setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
928 }
929
Mingming Yinbbd94ad2012-11-29 20:04:36 -0800930 audio_devices_t newDevice = getNewDevice(output, false /*fromCache*/);
931 // delay the device switch by twice the latency because stopOutput() is executed when
932 // the track stop() command is received and at that time the audio track buffer can
933 // still contain data that needs to be drained. The latency only covers the audio HAL
934 // and kernel buffers. Also the latency does not always include additional delay in the
935 // audio path (audio DSP, CODEC ...)
936 setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
937
938 // force restoring the device selection on other active outputs if it differs from the
939 // one being selected for this output
940 for (size_t i = 0; i < mOutputs.size(); i++) {
941 audio_io_handle_t curOutput = mOutputs.keyAt(i);
942 AudioOutputDescriptor *desc = mOutputs.valueAt(i);
943 if (curOutput != output &&
944 desc->refCount() != 0 &&
945 outputDesc->sharesHwModuleWith(desc) &&
946 newDevice != desc->device()) {
947 setOutputDevice(curOutput,
948 getNewDevice(curOutput, false /*fromCache*/),
949 true,
950 outputDesc->mLatency*2);
951 }
952 }
953 // update the outputs if stopping one with a stream that can affect notification routing
954 handleNotificationRoutingForStream(stream);
955 }
956 return NO_ERROR;
957 } else {
958 ALOGW("stopOutput() refcount is already 0 for output %d", output);
959 return INVALID_OPERATION;
960 }
961}
962
Mingming Yin979666c2012-12-09 23:22:36 -0800963
964audio_io_handle_t AudioPolicyManager::getInput(int inputSource,
965 uint32_t samplingRate,
966 uint32_t format,
967 uint32_t channelMask,
968 AudioSystem::audio_in_acoustics acoustics)
969{
970 audio_io_handle_t input = 0;
971 audio_devices_t device = getDeviceForInputSource(inputSource);
972
973 ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
974 inputSource, samplingRate, format, channelMask, acoustics);
975
976 if (device == AUDIO_DEVICE_NONE) {
977 ALOGW("getInput() could not find device for inputSource %d", inputSource);
978 return 0;
979 }
980
981 // adapt channel selection to input source
982 switch(inputSource) {
983 case AUDIO_SOURCE_VOICE_UPLINK:
984 channelMask |= AudioSystem::CHANNEL_IN_VOICE_UPLINK;
985 break;
986 case AUDIO_SOURCE_VOICE_DOWNLINK:
987 channelMask |= AudioSystem::CHANNEL_IN_VOICE_DNLINK;
988 break;
989 case AUDIO_SOURCE_VOICE_CALL:
990 channelMask |= (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
991 break;
992 default:
993 break;
994 }
995
996 IOProfile *profile = getInputProfile(device,
997 samplingRate,
998 format,
999 channelMask);
1000 if (profile == NULL) {
1001 ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d,"
1002 "channelMask %04x",
1003 device, samplingRate, format, channelMask);
1004 return 0;
1005 }
1006
1007 if (profile->mModule->mHandle == 0) {
1008 ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
1009 return 0;
1010 }
1011
1012 AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
1013
1014 inputDesc->mInputSource = inputSource;
1015 inputDesc->mDevice = device;
1016 inputDesc->mSamplingRate = samplingRate;
1017 inputDesc->mFormat = (audio_format_t)format;
1018 inputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
1019 inputDesc->mRefCount = 0;
1020 input = mpClientInterface->openInput(profile->mModule->mHandle,
1021 &inputDesc->mDevice,
1022 &inputDesc->mSamplingRate,
1023 &inputDesc->mFormat,
1024 &inputDesc->mChannelMask);
1025
1026 // only accept input with the exact requested set of parameters
1027 if (input == 0 ||
1028 (samplingRate != inputDesc->mSamplingRate) ||
1029 (format != inputDesc->mFormat) ||
1030 (channelMask != inputDesc->mChannelMask)) {
1031 ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d",
1032 samplingRate, format, channelMask);
1033 if (input != 0) {
1034 mpClientInterface->closeInput(input);
1035 }
1036 delete inputDesc;
1037 return 0;
1038 }
1039 mInputs.add(input, inputDesc);
1040 return input;
1041}
1042
1043/*
1044Overwriting this function from base class to allow 2 acitve AudioRecord clients in case of FM.
1045One for FM A2DP playbck and other for FM recording.
1046*/
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001047status_t AudioPolicyManager::startInput(audio_io_handle_t input)
1048{
1049 ALOGV("startInput() input %d", input);
1050 ssize_t index = mInputs.indexOfKey(input);
1051 if (index < 0) {
1052 ALOGW("startInput() unknow input %d", input);
1053 return BAD_VALUE;
1054 }
1055 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1056
Mingming Yin979666c2012-12-09 23:22:36 -08001057/*
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001058#ifdef AUDIO_POLICY_TEST
1059 if (mTestInput == 0)
1060#endif //AUDIO_POLICY_TEST
1061 {
1062 // refuse 2 active AudioRecord clients at the same time
1063 if (getActiveInput() != 0) {
1064 ALOGW("startInput() input %d failed: other input already started", input);
1065 return INVALID_OPERATION;
1066 }
1067 }
Mingming Yin979666c2012-12-09 23:22:36 -08001068*/
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001069
1070 AudioParameter param = AudioParameter();
1071 param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
1072
1073 param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
1074
1075 // use Voice Recognition mode or not for this input based on input source
1076 int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
1077 param.addInt(String8("vr_mode"), vr_enabled);
1078 ALOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
1079
Srikanth Kattadd170562013-04-24 16:21:22 +05301080 //to pass on if camcorder mode is enabled to HAL
1081 int camcorder_enabled = inputDesc->mInputSource == AUDIO_SOURCE_CAMCORDER ? 1 : 0;
1082 param.addInt(String8("camcorder_mode"), camcorder_enabled);
1083
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001084 mpClientInterface->setParameters(input, param.toString());
1085
1086 inputDesc->mRefCount = 1;
1087 return NO_ERROR;
1088}
1089
Mingming Yin979666c2012-12-09 23:22:36 -08001090status_t AudioPolicyManager::stopInput(audio_io_handle_t input)
1091{
1092 ALOGV("stopInput() input %d", input);
1093 ssize_t index = mInputs.indexOfKey(input);
1094 if (index < 0) {
1095 ALOGW("stopInput() unknow input %d", input);
1096 return BAD_VALUE;
1097 }
1098 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1099
1100 if (inputDesc->mRefCount == 0) {
1101 ALOGW("stopInput() input %d already stopped", input);
1102 return INVALID_OPERATION;
1103 } else {
1104 AudioParameter param = AudioParameter();
1105 param.addInt(String8(AudioParameter::keyRouting), 0);
1106 mpClientInterface->setParameters(input, param.toString());
1107 setOutputDevice(mPrimaryOutput, getNewDevice(mPrimaryOutput, true), true);
1108 inputDesc->mRefCount = 0;
1109 return NO_ERROR;
1110 }
1111}
1112
1113
1114status_t AudioPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream,
1115 int index,
1116 audio_devices_t device)
1117{
1118
1119 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1120 return BAD_VALUE;
1121 }
1122 if (!audio_is_output_device(device)) {
1123 return BAD_VALUE;
1124 }
1125
1126 // Force max volume if stream cannot be muted
1127 if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
1128
1129 ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1130 stream, device, index);
1131
1132 // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1133 // clear all device specific values
1134 if ((device == AUDIO_DEVICE_OUT_DEFAULT) && (AUDIO_DEVICE_OUT_DEFAULT != AUDIO_DEVICE_OUT_SPEAKER)) {
1135 mStreams[stream].mIndexCur.clear();
1136 }
1137 mStreams[stream].mIndexCur.add(device, index);
1138
1139 // compute and apply stream volume on all outputs according to connected device
1140 status_t status = NO_ERROR;
1141 for (size_t i = 0; i < mOutputs.size(); i++) {
1142 audio_devices_t curDevice =
1143 getDeviceForVolume(mOutputs.valueAt(i)->device());
1144 if (device == curDevice) {
1145 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1146 if (volStatus != NO_ERROR) {
1147 status = volStatus;
1148 }
1149 }
1150 }
1151 return status;
1152}
1153
1154
1155status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device,
1156 AudioSystem::device_connection_state state,
1157 SortedVector<audio_io_handle_t>& outputs)
1158{
1159 AudioOutputDescriptor *desc;
1160
1161 if (state == AudioSystem::DEVICE_STATE_AVAILABLE) {
1162 // first list already open outputs that can be routed to this device
1163 for (size_t i = 0; i < mOutputs.size(); i++) {
1164 desc = mOutputs.valueAt(i);
1165 if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices & device)) {
1166 ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
1167 outputs.add(mOutputs.keyAt(i));
1168 }
1169 }
1170 // then look for output profiles that can be routed to this device
1171 SortedVector<IOProfile *> profiles;
1172 for (size_t i = 0; i < mHwModules.size(); i++)
1173 {
1174 if (mHwModules[i]->mHandle == 0) {
1175 continue;
1176 }
1177 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
1178 {
1179 if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices & device) {
1180 ALOGV("checkOutputsForDevice(): adding profile %d from module %d", j, i);
1181 profiles.add(mHwModules[i]->mOutputProfiles[j]);
1182 }
1183 }
1184 }
1185
1186 if (profiles.isEmpty() && outputs.isEmpty()) {
1187 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
1188 return BAD_VALUE;
1189 }
1190
1191 // open outputs for matching profiles if needed. Direct outputs are also opened to
1192 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
1193 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
1194 IOProfile *profile = profiles[profile_index];
1195
1196 // nothing to do if one output is already opened for this profile
1197 size_t j;
1198 for (j = 0; j < mOutputs.size(); j++) {
1199 desc = mOutputs.valueAt(j);
1200 if (!desc->isDuplicated() && desc->mProfile == profile) {
1201 break;
1202 }
1203 }
1204 if (j != mOutputs.size()) {
1205 continue;
1206 }
1207
1208 ALOGV("opening output for device %08x", device);
1209 desc = new AudioOutputDescriptor(profile);
1210 desc->mDevice = device;
1211 audio_io_handle_t output = 0;
1212 if (!(desc->mFlags & AUDIO_OUTPUT_FLAG_LPA || desc->mFlags & AUDIO_OUTPUT_FLAG_TUNNEL ||
1213 desc->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)) {
1214 output = mpClientInterface->openOutput(profile->mModule->mHandle,
1215 &desc->mDevice,
1216 &desc->mSamplingRate,
1217 &desc->mFormat,
1218 &desc->mChannelMask,
1219 &desc->mLatency,
1220 desc->mFlags);
1221 }
1222 if (output != 0) {
1223 if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1224 String8 reply;
1225 char *value;
1226 if (profile->mSamplingRates[0] == 0) {
1227 reply = mpClientInterface->getParameters(output,
1228 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
1229 ALOGV("checkOutputsForDevice() direct output sup sampling rates %s",
1230 reply.string());
1231 value = strpbrk((char *)reply.string(), "=");
1232 if (value != NULL) {
1233 loadSamplingRates(value, profile);
1234 }
1235 }
1236 if (profile->mFormats[0] == 0) {
1237 reply = mpClientInterface->getParameters(output,
1238 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
1239 ALOGV("checkOutputsForDevice() direct output sup formats %s",
1240 reply.string());
1241 value = strpbrk((char *)reply.string(), "=");
1242 if (value != NULL) {
1243 loadFormats(value, profile);
1244 }
1245 }
1246 if (profile->mChannelMasks[0] == 0) {
1247 reply = mpClientInterface->getParameters(output,
1248 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
1249 ALOGV("checkOutputsForDevice() direct output sup channel masks %s",
1250 reply.string());
1251 value = strpbrk((char *)reply.string(), "=");
1252 if (value != NULL) {
1253 loadOutChannels(value + 1, profile);
1254 }
1255 }
1256 if (((profile->mSamplingRates[0] == 0) &&
1257 (profile->mSamplingRates.size() < 2)) ||
1258 ((profile->mFormats[0] == 0) &&
1259 (profile->mFormats.size() < 2)) ||
1260 ((profile->mFormats[0] == 0) &&
1261 (profile->mChannelMasks.size() < 2))) {
1262 ALOGW("checkOutputsForDevice() direct output missing param");
1263 output = 0;
1264 } else {
1265 addOutput(output, desc);
1266 }
1267 } else {
1268 audio_io_handle_t duplicatedOutput = 0;
1269 // add output descriptor
1270 addOutput(output, desc);
1271 // set initial stream volume for device
1272 applyStreamVolumes(output, device, 0, true);
1273
1274 //TODO: configure audio effect output stage here
1275
1276 // open a duplicating output thread for the new output and the primary output
1277 duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
1278 mPrimaryOutput);
1279 if (duplicatedOutput != 0) {
1280 // add duplicated output descriptor
1281 AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL);
1282 dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
1283 dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
1284 dupOutputDesc->mSamplingRate = desc->mSamplingRate;
1285 dupOutputDesc->mFormat = desc->mFormat;
1286 dupOutputDesc->mChannelMask = desc->mChannelMask;
1287 dupOutputDesc->mLatency = desc->mLatency;
1288 addOutput(duplicatedOutput, dupOutputDesc);
1289 applyStreamVolumes(duplicatedOutput, device, 0, true);
1290 } else {
1291 ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
1292 mPrimaryOutput, output);
1293 mpClientInterface->closeOutput(output);
1294 mOutputs.removeItem(output);
1295 output = 0;
1296 }
1297 }
1298 }
1299 if (output == 0) {
1300 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
1301 delete desc;
1302 profiles.removeAt(profile_index);
1303 profile_index--;
1304 } else {
1305 outputs.add(output);
1306 ALOGV("checkOutputsForDevice(): adding output %d", output);
1307 }
1308 }
1309
1310 if (profiles.isEmpty()) {
1311 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
1312 return BAD_VALUE;
1313 }
1314 } else {
1315 // check if one opened output is not needed any more after disconnecting one device
1316 for (size_t i = 0; i < mOutputs.size(); i++) {
1317 desc = mOutputs.valueAt(i);
1318 if (!desc->isDuplicated() &&
1319 !(desc->mProfile->mSupportedDevices & mAvailableOutputDevices)) {
1320 ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i));
1321 outputs.add(mOutputs.keyAt(i));
1322 }
1323 }
1324 for (size_t i = 0; i < mHwModules.size(); i++)
1325 {
1326 if (mHwModules[i]->mHandle == 0) {
1327 continue;
1328 }
1329 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
1330 {
1331 IOProfile *profile = mHwModules[i]->mOutputProfiles[j];
1332 if ((profile->mSupportedDevices & device) &&
1333 (profile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
1334 ALOGV("checkOutputsForDevice(): clearing direct output profile %d on module %d",
1335 j, i);
1336 if (profile->mSamplingRates[0] == 0) {
1337 profile->mSamplingRates.clear();
1338 profile->mSamplingRates.add(0);
1339 }
1340 if (profile->mFormats[0] == 0) {
1341 profile->mFormats.clear();
1342 profile->mFormats.add((audio_format_t)0);
1343 }
1344 if (profile->mChannelMasks[0] == 0) {
1345 profile->mChannelMasks.clear();
1346 profile->mChannelMasks.add((audio_channel_mask_t)0);
1347 }
1348 }
1349 }
1350 }
1351 }
1352 return NO_ERROR;
1353}
1354
1355audio_devices_t AudioPolicyManager::getNewDevice(audio_io_handle_t output, bool fromCache)
1356{
1357 audio_devices_t device = AUDIO_DEVICE_NONE;
1358
1359 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1360 AudioOutputDescriptor *primaryOutputDesc = mOutputs.valueFor(mPrimaryOutput);
Mingming Yin979666c2012-12-09 23:22:36 -08001361 // check the following by order of priority to request a routing change if necessary:
1362 // 1: the strategy enforced audible is active on the output:
1363 // use device for strategy enforced audible
1364 // 2: we are in call or the strategy phone is active on the output:
1365 // use device for strategy phone
1366 // 3: the strategy sonification is active on the output:
1367 // use device for strategy sonification
1368 // 4: the strategy "respectful" sonification is active on the output:
1369 // use device for strategy "respectful" sonification
1370 // 5: the strategy media is active on the output:
1371 // use device for strategy media
1372 // 6: the strategy DTMF is active on the output:
1373 // use device for strategy DTMF
Vicky Sehrawat6697adb2013-04-30 16:58:06 -07001374 if (outputDesc->isUsedByStrategy(STRATEGY_ENFORCED_AUDIBLE)) {
Mingming Yin979666c2012-12-09 23:22:36 -08001375 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
1376 } else if (isInCall() ||
Vicky Sehrawat6697adb2013-04-30 16:58:06 -07001377 outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
Mingming Yin979666c2012-12-09 23:22:36 -08001378 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
Vimal Puthanveed63ab11a2013-03-11 11:53:40 -07001379 } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)){
Mingming Yin979666c2012-12-09 23:22:36 -08001380 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
1381 } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION_RESPECTFUL)) {
1382 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
1383 } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
1384 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
1385 } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
1386 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
1387 }
1388
1389 ALOGV("getNewDevice() selected device %x", device);
1390 return device;
1391}
Mingming Yinfddaa942012-12-27 17:42:46 -08001392
1393AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
1394 AudioSystem::stream_type stream) {
1395 // stream to strategy mapping
1396 switch (stream) {
1397 case AudioSystem::VOICE_CALL:
1398 case AudioSystem::BLUETOOTH_SCO:
1399 return STRATEGY_PHONE;
1400 case AudioSystem::RING:
1401 case AudioSystem::ALARM:
1402 return STRATEGY_SONIFICATION;
1403 case AudioSystem::NOTIFICATION:
1404 return STRATEGY_SONIFICATION_RESPECTFUL;
1405 case AudioSystem::DTMF:
1406 return STRATEGY_DTMF;
1407 default:
1408 ALOGE("unknown stream type");
1409 case AudioSystem::SYSTEM:
1410 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1411 // while key clicks are played produces a poor result
1412 case AudioSystem::TTS:
1413 case AudioSystem::MUSIC:
1414#ifdef QCOM_FM_ENABLED
1415 case AudioSystem::FM:
1416#endif
1417 return STRATEGY_MEDIA;
1418 case AudioSystem::ENFORCED_AUDIBLE:
1419 return STRATEGY_ENFORCED_AUDIBLE;
1420 }
1421}
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001422audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
1423 bool fromCache)
1424{
1425 uint32_t device = AUDIO_DEVICE_NONE;
1426
1427 if (fromCache) {
1428 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
1429 strategy, mDeviceForStrategy[strategy]);
1430 return mDeviceForStrategy[strategy];
1431 }
1432
1433 switch (strategy) {
1434
1435 case STRATEGY_SONIFICATION_RESPECTFUL:
1436 if (isInCall()) {
1437 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1438 } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
1439 // while media is playing (or has recently played), use the same device
1440 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1441 } else {
1442 // when media is not playing anymore, fall back on the sonification behavior
1443 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1444 }
1445
1446 break;
1447
1448 case STRATEGY_DTMF:
1449 if (!isInCall()) {
1450 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1451 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1452 break;
1453 }
1454 // when in call, DTMF and PHONE strategies follow the same rules
1455 // FALL THROUGH
1456
1457 case STRATEGY_PHONE:
1458 // for phone strategy, we first consider the forced use and then the available devices by order
1459 // of priority
1460 switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
1461 case AudioSystem::FORCE_BT_SCO:
1462 if (!isInCall() || strategy != STRATEGY_DTMF) {
1463 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1464 if (device) break;
1465 }
1466 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1467 if (device) break;
1468 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
1469 if (device) break;
1470 // if SCO device is requested but no SCO device is available, fall back to default case
1471 // FALL THROUGH
1472
1473 default: // FORCE_NONE
1474 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
Subhash Chandra Bose Naripeddy1ec163f2012-12-21 18:12:05 -08001475 if (!isInCall())
1476 {
1477 if ((mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
1478 !mA2dpSuspended) {
1479 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1480 if (device) break;
1481 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1482 if (device) break;
1483 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001484 }
1485 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1486 if (device) break;
1487 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1488 if (device) break;
1489#ifdef QCOM_ANC_HEADSET_ENABLED
1490 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADPHONE;
1491 if (device) break;
1492 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADSET;
1493 if (device) break;
1494#endif
1495 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
1496 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1497 if (device) break;
1498 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
1499 if (device) break;
1500 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1501 if (device) break;
1502 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1503 if (device) break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001504 }
Vidyakumar Athotaebe85572012-12-27 19:17:12 -08001505 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1506 if (device) break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001507 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE;
1508 if (device) break;
1509 device = mDefaultOutputDevice;
1510 if (device == AUDIO_DEVICE_NONE) {
1511 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
1512 }
1513 break;
1514
1515 case AudioSystem::FORCE_SPEAKER:
1516 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
1517 // A2DP speaker when forcing to speaker output
1518 if (!isInCall() &&
1519 (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
1520 !mA2dpSuspended) {
1521 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1522 if (device) break;
1523 }
1524 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
1525 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1526 if (device) break;
1527 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
1528 if (device) break;
1529 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1530 if (device) break;
1531 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1532 if (device) break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001533 }
Vidyakumar Athotaebe85572012-12-27 19:17:12 -08001534 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1535 if (device) break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001536 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
1537 if (device) break;
1538 device = mDefaultOutputDevice;
1539 if (device == AUDIO_DEVICE_NONE) {
1540 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
1541 }
1542 break;
1543 }
1544#ifdef QCOM_FM_ENABLED
1545 if (mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001546 if (mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_SPEAKER) {
1547 device &= ~(AUDIO_DEVICE_OUT_WIRED_HEADSET);
1548 device &= ~(AUDIO_DEVICE_OUT_WIRED_HEADPHONE);
1549 device &= ~(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET);
1550 device |= AUDIO_DEVICE_OUT_SPEAKER;
1551 }
1552 }
1553#endif
1554 break;
1555
1556 case STRATEGY_SONIFICATION:
1557
1558 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1559 // handleIncallSonification().
1560 if (isInCall()) {
1561 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1562 break;
1563 }
1564 // FALL THROUGH
1565
1566 case STRATEGY_ENFORCED_AUDIBLE:
1567 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
1568 // except:
1569 // - when in call where it doesn't default to STRATEGY_PHONE behavior
1570 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
1571
1572 if ((strategy == STRATEGY_SONIFICATION) ||
1573 (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) {
1574 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
1575 if (device == AUDIO_DEVICE_NONE) {
1576 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
1577 }
1578 }
1579 // The second device used for sonification is the same as the device used by media strategy
1580 // FALL THROUGH
1581
1582 case STRATEGY_MEDIA: {
1583 uint32_t device2 = AUDIO_DEVICE_NONE;
1584 if (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_SPEAKER) {
1585 if (strategy != STRATEGY_SONIFICATION) {
Amal Paul061f10d2013-02-28 22:10:24 -08001586#ifdef QCOM_PROXY_DEVICE_ENABLED
1587 // no sonification on WFD sink
1588 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY;
1589#else
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001590 // no sonification on remote submix (e.g. WFD)
1591 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001592#endif
Amal Paul061f10d2013-02-28 22:10:24 -08001593 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001594 if ((device2 == AUDIO_DEVICE_NONE) &&
1595 (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
1596 !mA2dpSuspended) {
Mingming Yin979666c2012-12-09 23:22:36 -08001597 if (device2 == AUDIO_DEVICE_NONE) {
1598 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1599 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001600 if (device2 == AUDIO_DEVICE_NONE) {
1601 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1602 }
1603 if (device2 == AUDIO_DEVICE_NONE) {
1604 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1605 }
1606 }
1607 if (device2 == AUDIO_DEVICE_NONE) {
1608 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1609 }
1610 if (device2 == AUDIO_DEVICE_NONE) {
1611 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1612 }
1613#ifdef QCOM_ANC_HEADSET_ENABLED
1614 if (device2 == AUDIO_DEVICE_NONE) {
1615 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADPHONE;
1616 }
1617 if (device2 == AUDIO_DEVICE_NONE) {
1618 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANC_HEADSET;
1619 }
1620#endif
1621 if (device2 == AUDIO_DEVICE_NONE) {
1622 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1623 }
1624 if (device2 == AUDIO_DEVICE_NONE) {
1625 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
1626 }
1627 if (device2 == AUDIO_DEVICE_NONE) {
1628 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1629 }
1630 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
1631 // no sonification on aux digital (e.g. HDMI)
1632 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1633 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001634 if (device2 == AUDIO_DEVICE_NONE) {
Mingming Yin979666c2012-12-09 23:22:36 -08001635 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001636 }
1637#ifdef QCOM_FM_ENABLED
1638 if (device2 == AUDIO_DEVICE_NONE) {
1639 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM_TX;
1640 }
1641#endif
Mingming Yin979666c2012-12-09 23:22:36 -08001642 if (device2 == AUDIO_DEVICE_NONE) {
1643 device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
1644 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001645
1646 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
1647 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
1648 device |= device2;
Mingming Yinfddaa942012-12-27 17:42:46 -08001649 if (!device) {
1650 device = mDefaultOutputDevice;
1651 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001652 if (device == AUDIO_DEVICE_NONE) {
1653 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
1654 }
1655
1656 } else {
1657 //AudioSystem::FORCE_SPEAKER for STRATEGY_MEDIA
1658 device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
1659 }
1660
Vidyakumar Athota1b6657f2013-02-25 17:12:15 -08001661 if (isInCall()) {
1662 // when in call, get the device for Phone strategy
1663 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1664 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001665
1666 } break;
1667
1668 default:
1669 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1670 break;
1671 }
1672
1673 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1674 return device;
1675}
1676
1677uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
1678 audio_devices_t device,
1679 bool force,
1680 int delayMs)
1681
1682{
1683 ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
1684 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1685 AudioParameter param;
1686 uint32_t muteWaitMs = 0;
1687
1688 if (outputDesc->isDuplicated()) {
1689 muteWaitMs = setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
1690 muteWaitMs += setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
1691 return muteWaitMs;
1692 }
1693 // filter devices according to output selected
1694 device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices);
1695
1696 audio_devices_t prevDevice = outputDesc->mDevice;
1697
1698 ALOGV("setOutputDevice() prevDevice %04x", prevDevice);
1699
1700 if (device != AUDIO_DEVICE_NONE) {
1701 outputDesc->mDevice = device;
1702 }
1703 muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
1704
1705 // Do not change the routing if:
1706 // - the requested device is AUDIO_DEVICE_NONE
1707 // - the requested device is the same as current device and force is not specified.
1708 // Doing this check here allows the caller to call setOutputDevice() without conditions
Yamit Mehta8f883e22013-05-06 09:53:55 +05301709 if ((device == AUDIO_DEVICE_NONE) || ((device == prevDevice) && !force)) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001710 ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
1711 return muteWaitMs;
1712 }
Subhash Chandra Bose Naripeddy1ec163f2012-12-21 18:12:05 -08001713 if (device == prevDevice) {
1714 ALOGV("setOutputDevice() Call routing with same device with zero delay ");
1715 delayMs = 0;
1716 }
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001717 ALOGV("setOutputDevice() changing device:%x",device);
1718 // do the routing
1719 param.addInt(String8(AudioParameter::keyRouting), (int)device);
1720 mpClientInterface->setParameters(output, param.toString(), delayMs);
1721
1722 // update stream volumes according to new device
1723 applyStreamVolumes(output, device, delayMs);
1724
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001725 return muteWaitMs;
1726}
1727
1728audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource)
1729{
1730 uint32_t device = AUDIO_DEVICE_NONE;
1731
1732 switch(inputSource) {
1733 case AUDIO_SOURCE_DEFAULT:
1734 case AUDIO_SOURCE_MIC:
1735 case AUDIO_SOURCE_VOICE_RECOGNITION:
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001736 if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
1737 mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1738 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
1739 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1740 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
1741#ifdef QCOM_ANC_HEADSET_ENABLED
1742 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_ANC_HEADSET) {
1743 device = AUDIO_DEVICE_IN_ANC_HEADSET;
1744#endif
1745 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) {
1746 device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
1747 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1748 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
1749 }
1750 break;
Mingming Yin979666c2012-12-09 23:22:36 -08001751 case AUDIO_SOURCE_VOICE_COMMUNICATION:
1752 device = AUDIO_DEVICE_IN_COMMUNICATION;
1753 break;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001754 case AUDIO_SOURCE_CAMCORDER:
1755 if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) {
1756 device = AUDIO_DEVICE_IN_BACK_MIC;
Srikanth Kattadd170562013-04-24 16:21:22 +05301757 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1758 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
1759 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) {
1760 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
1761 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_AUX_DIGITAL) {
1762 device = AUDIO_DEVICE_IN_AUX_DIGITAL;
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001763 } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
1764 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
1765 }
1766 break;
1767 case AUDIO_SOURCE_VOICE_UPLINK:
1768 case AUDIO_SOURCE_VOICE_DOWNLINK:
1769 case AUDIO_SOURCE_VOICE_CALL:
1770 if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) {
1771 device = AUDIO_DEVICE_IN_VOICE_CALL;
1772 }
1773 break;
1774 case AUDIO_SOURCE_REMOTE_SUBMIX:
1775 if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
1776 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1777 }
1778 break;
1779#ifdef QCOM_FM_ENABLED
1780 case AUDIO_SOURCE_FM_RX:
1781 device = AUDIO_DEVICE_IN_FM_RX;
1782 break;
1783 case AUDIO_SOURCE_FM_RX_A2DP:
1784 device = AUDIO_DEVICE_IN_FM_RX_A2DP;
1785 break;
1786#endif
1787 default:
1788 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
1789 break;
1790 }
1791 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
1792 return device;
1793}
1794
1795
Mingming Yin979666c2012-12-09 23:22:36 -08001796
1797
1798audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
1799{
1800 if (device == AUDIO_DEVICE_NONE) {
1801 // this happens when forcing a route update and no track is active on an output.
1802 // In this case the returned category is not important.
1803 device = AUDIO_DEVICE_OUT_SPEAKER;
1804 } else if (AudioSystem::popCount(device) > 1) {
1805 // Multiple device selection is either:
1806 // - speaker + one other device: give priority to speaker in this case.
1807 // - one A2DP device + another device: happens with duplicated output. In this case
1808 // retain the device on the A2DP output as the other must not correspond to an active
1809 // selection if not the speaker.
1810 if (device & AUDIO_DEVICE_OUT_SPEAKER) {
1811 device = AUDIO_DEVICE_OUT_SPEAKER;
1812 } else if ((device & AUDIO_DEVICE_OUT_WIRED_HEADSET) != 0) {
1813 device = AUDIO_DEVICE_OUT_WIRED_HEADSET;
1814 } else if ((device & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) != 0) {
1815 device = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1816 } else {
1817 device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
1818 }
1819 }
1820
1821 ALOGW_IF(AudioSystem::popCount(device) != 1,
1822 "getDeviceForVolume() invalid device combination: %08x",
1823 device);
1824
1825 return device;
1826}
1827
1828AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
1829{
1830 switch(getDeviceForVolume(device)) {
1831 case AUDIO_DEVICE_OUT_EARPIECE:
1832 return DEVICE_CATEGORY_EARPIECE;
1833 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
1834 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
1835 case AUDIO_DEVICE_OUT_ANC_HEADSET:
1836 case AUDIO_DEVICE_OUT_ANC_HEADPHONE:
1837 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
1838 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
1839 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
1840 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
Mingming Yinfddaa942012-12-27 17:42:46 -08001841#ifdef QCOM_FM_ENABLED
Mingming Yin979666c2012-12-09 23:22:36 -08001842 case AUDIO_DEVICE_OUT_FM:
Mingming Yinfddaa942012-12-27 17:42:46 -08001843#endif
Mingming Yin979666c2012-12-09 23:22:36 -08001844 return DEVICE_CATEGORY_HEADSET;
1845 case AUDIO_DEVICE_OUT_SPEAKER:
1846 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
1847 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
1848 case AUDIO_DEVICE_OUT_AUX_DIGITAL:
1849 case AUDIO_DEVICE_OUT_USB_ACCESSORY:
1850 case AUDIO_DEVICE_OUT_USB_DEVICE:
1851 case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
1852 case AUDIO_DEVICE_OUT_PROXY:
1853 default:
1854 return DEVICE_CATEGORY_SPEAKER;
1855 }
1856}
Sriranjan Srikantamcbfe2eb2013-06-18 11:58:00 +05301857
1858bool AudioPolicyManager::isDirectOutput(audio_io_handle_t output) {
1859 for (size_t i = 0; i < mOutputs.size(); i++) {
1860 audio_io_handle_t curOutput = mOutputs.keyAt(i);
1861 AudioOutputDescriptor *desc = mOutputs.valueAt(i);
1862 if ((curOutput == output) && (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
1863 return true;
1864 }
1865 }
1866 return false;
1867}
1868
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001869status_t AudioPolicyManager::checkAndSetVolume(int stream,
1870 int index,
1871 audio_io_handle_t output,
1872 audio_devices_t device,
1873 int delayMs,
1874 bool force)
1875{
1876 // do not change actual stream volume if the stream is muted
1877 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
1878 ALOGVV("checkAndSetVolume() stream %d muted count %d",
1879 stream, mOutputs.valueFor(output)->mMuteCount[stream]);
1880 return NO_ERROR;
1881 }
1882
1883 // do not change in call volume if bluetooth is connected and vice versa
1884 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
1885 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
1886 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
1887 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
1888 return INVALID_OPERATION;
1889 }
1890
1891 float volume = computeVolume(stream, index, output, device);
1892 // We actually change the volume if:
1893 // - the float value returned by computeVolume() changed
1894 // - the force flag is set
1895 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
1896#ifdef QCOM_FM_ENABLED
1897 (stream == AudioSystem::FM) ||
1898#endif
1899 force) {
1900 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
1901 ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
1902 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
1903 // enabled
1904 if (stream == AudioSystem::BLUETOOTH_SCO) {
1905 mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);
1906#ifdef QCOM_FM_ENABLED
1907 } else if (stream == AudioSystem::FM) {
1908 float fmVolume = -1.0;
1909 fmVolume = computeVolume(stream, index, output, device);
1910 if (fmVolume >= 0) {
1911 if(output == mPrimaryOutput)
1912 mpClientInterface->setFmVolume(fmVolume, delayMs);
1913 else if(mHasA2dp && output == getA2dpOutput())
1914 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1915 }
1916 return NO_ERROR;
1917#endif
1918 }
1919 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1920 }
1921
1922 if (stream == AudioSystem::VOICE_CALL ||
1923 stream == AudioSystem::BLUETOOTH_SCO) {
1924 float voiceVolume;
1925 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
1926 if (stream == AudioSystem::VOICE_CALL) {
1927 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
1928 } else {
1929 voiceVolume = 1.0;
1930 }
1931
1932 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
1933
1934 // Force voice volume to max when Vgs is set for bluetooth SCO as volume is managed by the headset
1935 if (stream == AudioSystem::BLUETOOTH_SCO) {
1936 String8 key ("bt_headset_vgs");
1937 mpClientInterface->getParameters(output,key);
1938 AudioParameter result(mpClientInterface->getParameters(0,key));
1939 int value;
1940 if (result.getInt(String8("isVGS"),value) == NO_ERROR) {
1941 ALOGV("Use BT-SCO Voice Volume");
1942 voiceVolume = 1.0;
1943 }
1944 }
1945
Sriranjan Srikantamcbfe2eb2013-06-18 11:58:00 +05301946 if (voiceVolume != mLastVoiceVolume && (output == mPrimaryOutput ||
1947 isDirectOutput(output))) {
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001948 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1949 mLastVoiceVolume = voiceVolume;
1950 }
1951 }
1952
1953 return NO_ERROR;
1954}
1955
1956
1957void AudioPolicyManager::checkA2dpSuspend()
1958{
1959
1960 // suspend A2DP output if:
1961 // (NOT already suspended) &&
1962 // ((SCO device is connected &&
1963 // (forced usage for communication || for record is SCO))) ||
1964 // (phone state is ringing || in call)
1965 //
1966 // restore A2DP output if:
1967 // (Already suspended) &&
1968 // ((SCO device is NOT connected ||
1969 // (forced usage NOT for communication && NOT for record is SCO))) &&
1970 // (phone state is NOT ringing && NOT in call)
1971 //
1972 if (mA2dpSuspended) {
1973 if (((mScoDeviceAddress == "") ||
1974 ((mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO) &&
Karthik Reddy Katta67714332013-03-22 19:04:07 +05301975 (mForceUse[AudioSystem::FOR_RECORD] != AudioSystem::FORCE_BT_SCO))) ||
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001976 ((mPhoneState != AudioSystem::MODE_IN_CALL) &&
1977 (mPhoneState != AudioSystem::MODE_RINGTONE))) {
1978
1979 mA2dpSuspended = false;
1980 }
1981 } else {
1982 if (((mScoDeviceAddress != "") &&
1983 ((mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
Karthik Reddy Katta67714332013-03-22 19:04:07 +05301984 (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO))) &&
Mingming Yinbbd94ad2012-11-29 20:04:36 -08001985 ((mPhoneState == AudioSystem::MODE_IN_CALL) ||
1986 (mPhoneState == AudioSystem::MODE_RINGTONE))) {
1987
1988 mA2dpSuspended = true;
1989 }
1990 }
1991}
1992
1993audio_io_handle_t AudioPolicyManager::getA2dpOutput()
1994{
1995 return 0;
1996}
1997
1998//private function, no changes from AudioPolicyManagerBase
1999void AudioPolicyManager::handleNotificationRoutingForStream(AudioSystem::stream_type stream) {
2000 switch(stream) {
2001 case AudioSystem::MUSIC:
2002 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
2003 updateDevicesAndOutputs();
2004 break;
2005 default:
2006 break;
2007 }
2008}
2009
Iliyan Malchev4765c432012-06-11 14:36:16 -07002010
Subhash Chandra Bose Naripeddy908253a2012-12-07 11:57:25 -08002011AudioPolicyManagerBase::IOProfile *AudioPolicyManager::getProfileForDirectOutput(
2012 audio_devices_t device,
2013 uint32_t samplingRate,
2014 uint32_t format,
2015 uint32_t channelMask,
2016 audio_output_flags_t flags)
2017{
2018 if( !((flags & AUDIO_OUTPUT_FLAG_LPA) ||
2019 (flags & AUDIO_OUTPUT_FLAG_TUNNEL)||
2020 (flags & AUDIO_OUTPUT_FLAG_VOIP_RX)) )
2021 flags = AUDIO_OUTPUT_FLAG_DIRECT;
2022
2023 for (size_t i = 0; i < mHwModules.size(); i++) {
2024 if (mHwModules[i]->mHandle == 0) {
2025 continue;
2026 }
2027 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
2028 AudioPolicyManagerBase::IOProfile *profile = mHwModules[i]->mOutputProfiles[j];
2029 if (isCompatibleProfile(profile, device, samplingRate, format,
2030 channelMask,
2031 flags)) {
2032 if (mAvailableOutputDevices & profile->mSupportedDevices) {
2033 return mHwModules[i]->mOutputProfiles[j];
2034 }
2035 }
2036 }
2037 }
2038 return 0;
2039}
2040
2041bool AudioPolicyManager::isCompatibleProfile(AudioPolicyManagerBase::IOProfile *profile,
2042 audio_devices_t device,
2043 uint32_t samplingRate,
2044 uint32_t format,
2045 uint32_t channelMask,
2046 audio_output_flags_t flags)
2047{
2048 if ((profile->mSupportedDevices & device) != device) {
2049 return false;
2050 }
2051 if (profile->mFlags != flags) {
2052 return false;
2053 }
2054 if (samplingRate != 0) {
2055 size_t i;
2056 for (i = 0; i < profile->mSamplingRates.size(); i++)
2057 {
2058 if (profile->mSamplingRates[i] == samplingRate) {
2059 break;
2060 }
2061 }
2062 if (i == profile->mSamplingRates.size()) {
2063 return false;
2064 }
2065 }
2066 if (format != 0) {
2067 size_t i;
2068 for (i = 0; i < profile->mFormats.size(); i++)
2069 {
2070 if (profile->mFormats[i] == format) {
2071 break;
2072 }
2073 }
2074 if (i == profile->mFormats.size()) {
2075 return false;
2076 }
2077 }
2078 if (channelMask != 0) {
2079 size_t i;
2080 for (i = 0; i < profile->mChannelMasks.size(); i++)
2081 {
2082 if (profile->mChannelMasks[i] == channelMask) {
2083 break;
2084 }
2085 }
2086 if (i == profile->mChannelMasks.size()) {
2087 return false;
2088 }
2089 }
2090 ALOGD(" profile found: device %x, flags %x, samplingrate %d,\
2091 format %x, channelMask %d",
2092 device, flags, samplingRate, format, channelMask);
2093 return true;
2094}
Ajay Dudani9746c472012-06-18 16:01:16 -07002095
Mingming Yin9b79f6d2013-01-09 15:43:18 -08002096bool AudioPolicyManager::platform_is_Fusion3()
2097{
2098 char platform[128], baseband[128];
2099 property_get("ro.board.platform", platform, "");
2100 property_get("ro.baseband", baseband, "");
2101 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband))
2102 return true;
2103 else
2104 return false;
2105}
2106
Iliyan Malchev4765c432012-06-11 14:36:16 -07002107extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
2108{
2109 return new AudioPolicyManager(clientInterface);
2110}
2111
2112extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
2113{
2114 delete interface;
2115}
2116
Mingming Yinbbd94ad2012-11-29 20:04:36 -08002117
2118}; // namespace android