blob: 65bad3c483a69518b139bb2e9cfef322a49aed50 [file] [log] [blame]
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07001/*
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07003 * Not a contribution.
4 *
5 * Copyright (C) 2009 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#define LOG_TAG "AudioPolicyManager"
21//#define LOG_NDEBUG 0
22
23//#define VERY_VERBOSE_LOGGING
24#ifdef VERY_VERBOSE_LOGGING
25#define ALOGVV ALOGV
26#else
27#define ALOGVV(a...) do { } while(0)
28#endif
29
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070030// A device mask for all audio input devices that are considered "virtual" when evaluating
31// active inputs in getActiveInput()
32#ifdef AUDIO_EXTN_FM_ENABLED
33#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | AUDIO_DEVICE_IN_FM_RX_A2DP)
34#else
35#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX
36#endif
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070037// A device mask for all audio output devices that are considered "remote" when evaluating
38// active output devices in isStreamActiveRemotely()
39#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070040// A device mask for all audio input and output devices where matching inputs/outputs on device
41// type alone is not enough: the address must match too
42#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
43 AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070044
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070045#include <inttypes.h>
Mingming Yin0ae14ea2014-07-09 17:55:56 -070046#include <math.h>
Mingming Yin0670f162014-06-12 16:05:49 -070047
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070048#include <cutils/properties.h>
49#include <utils/Log.h>
50#include <hardware/audio.h>
51#include <hardware/audio_effect.h>
52#include <media/AudioParameter.h>
53#include <soundtrigger/SoundTrigger.h>
54#include "AudioPolicyManager.h"
55
56namespace android {
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070057
58// ----------------------------------------------------------------------------
59// AudioPolicyInterface implementation
60// ----------------------------------------------------------------------------
61
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070062status_t AudioPolicyManagerCustom::setDeviceConnectionState(audio_devices_t device,
63 audio_policy_dev_state_t state,
64 const char *device_address)
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070065{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070066 String8 address = (device_address == NULL) ? String8("") : String8(device_address);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070067
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070068 ALOGV("setDeviceConnectionState() device: %x, state %d, address %s",
69 device, state, address.string());
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070070
71 // connect/disconnect only 1 device at a time
72 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
73
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070074 // handle output devices
75 if (audio_is_output_device(device)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070076 SortedVector <audio_io_handle_t> outputs;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070077
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070078 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
79 devDesc->mAddress = address;
80 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070081
82 // save a copy of the opened output descriptors before any output is opened or closed
83 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
84 mPreviousOutputs = mOutputs;
85 switch (state)
86 {
87 // handle output device connection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070088 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
89 if (index >= 0) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -070090#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
91 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070092 if (!strncmp(device_address, "hdmi_spkr", 9)) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -070093 mHdmiAudioDisabled = false;
94 } else {
95 mHdmiAudioEvent = true;
96 }
97 }
98#endif
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070099 ALOGW("setDeviceConnectionState() device already connected: %x", device);
100 return INVALID_OPERATION;
101 }
102 ALOGV("setDeviceConnectionState() connecting device %x", device);
103
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700104 // register new device as available
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700105 index = mAvailableOutputDevices.add(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700106
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700107#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
108 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700109 if (!strncmp(device_address, "hdmi_spkr", 9)) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700110 mHdmiAudioDisabled = false;
111 } else {
112 mHdmiAudioEvent = true;
113 }
114 if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700115 mAvailableOutputDevices.remove(devDesc);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700116 }
117 }
118#endif
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700119 if (index >= 0) {
120 sp<HwModule> module = getModuleForDevice(device);
121 if (module == 0) {
122 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
123 device);
124 mAvailableOutputDevices.remove(devDesc);
125 return INVALID_OPERATION;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700126 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700127 mAvailableOutputDevices[index]->mId = nextUniqueId();
128 mAvailableOutputDevices[index]->mModule = module;
129 } else {
130 return NO_MEMORY;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700131 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700132
133 if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) {
134 mAvailableOutputDevices.remove(devDesc);
135 return INVALID_OPERATION;
136 }
137 // outputs should never be empty here
138 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
139 "checkOutputsForDevice() returned no outputs but status OK");
140 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
141 outputs.size());
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700142 break;
143 // handle output device disconnection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700144 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
145 if (index < 0) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700146#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
147 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700148 if (!strncmp(device_address, "hdmi_spkr", 9)) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700149 mHdmiAudioDisabled = true;
150 } else {
151 mHdmiAudioEvent = false;
152 }
153 }
154#endif
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700155 ALOGW("setDeviceConnectionState() device not connected: %x", device);
156 return INVALID_OPERATION;
157 }
158
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700159 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
160
161 // Set Disconnect to HALs
162 AudioParameter param = AudioParameter(address);
163 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
164 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
165
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700166 // remove device from available output devices
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700167 mAvailableOutputDevices.remove(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700168
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700169#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
170 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700171 if (!strncmp(device_address, "hdmi_spkr", 9)) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700172 mHdmiAudioDisabled = true;
173 } else {
174 mHdmiAudioEvent = false;
175 }
176 }
177#endif
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700178 checkOutputsForDevice(devDesc, state, outputs, address);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700179 } break;
180
181 default:
182 ALOGE("setDeviceConnectionState() invalid state: %x", state);
183 return BAD_VALUE;
184 }
185
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700186 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
187 // output is suspended before any tracks are moved to it
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700188 checkA2dpSuspend();
189 checkOutputForAllStrategies();
190 // outputs must be closed after checkOutputForAllStrategies() is executed
191 if (!outputs.isEmpty()) {
192 for (size_t i = 0; i < outputs.size(); i++) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700193 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700194 // close unused outputs after device disconnection or direct outputs that have been
195 // opened by checkOutputsForDevice() to query dynamic parameters
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700196 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700197 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
198 (desc->mDirectOpenCount == 0))) {
199 closeOutput(outputs[i]);
200 }
201 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700202 // check again after closing A2DP output to reset mA2dpSuspended if needed
203 checkA2dpSuspend();
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700204 }
205
206 updateDevicesAndOutputs();
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700207 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
208 if (mPhoneState == AUDIO_MODE_IN_CALL) {
209 updateCallRouting(newDevice);
210 }
211
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700212#ifdef AUDIO_EXTN_FM_ENABLED
213 if(device == AUDIO_DEVICE_OUT_FM) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700214 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
215 mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AUDIO_STREAM_MUSIC, 1);
216 newDevice = (audio_devices_t)(getNewOutputDevice(mPrimaryOutput, false) | AUDIO_DEVICE_OUT_FM);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700217 } else {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700218 mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AUDIO_STREAM_MUSIC, -1);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700219 }
220
221 AudioParameter param = AudioParameter();
222 param.addInt(String8("handle_fm"), (int)newDevice);
223 ALOGV("setDeviceConnectionState() setParameters handle_fm");
224 mpClientInterface->setParameters(mPrimaryOutput, param.toString());
225 }
226#endif
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700227 for (size_t i = 0; i < mOutputs.size(); i++) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700228 audio_io_handle_t output = mOutputs.keyAt(i);
229 if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
230 audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i),
231 true /*fromCache*/);
232 // do not force device change on duplicated output because if device is 0, it will
233 // also force a device 0 for the two outputs it is duplicated to which may override
234 // a valid device selection on those outputs.
235 bool force = !mOutputs.valueAt(i)->isDuplicated()
236 && (!deviceDistinguishesOnAddress(device)
237 // always force when disconnecting (a non-duplicated device)
238 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
239 setOutputDevice(output, newDevice, force, 0);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700240 }
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700241 }
242
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700243 mpClientInterface->onAudioPortListUpdate();
244 return NO_ERROR;
245 } // end if is output device
246
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700247 // handle input devices
248 if (audio_is_input_device(device)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700249 SortedVector <audio_io_handle_t> inputs;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700250
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700251 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
252 devDesc->mAddress = address;
253 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700254 switch (state)
255 {
256 // handle input device connection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700257 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
258 if (index >= 0) {
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700259 ALOGW("setDeviceConnectionState() device already connected: %d", device);
260 return INVALID_OPERATION;
261 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700262 sp<HwModule> module = getModuleForDevice(device);
263 if (module == NULL) {
264 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
265 device);
266 return INVALID_OPERATION;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700267 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700268 if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) {
269 return INVALID_OPERATION;
270 }
271
272 index = mAvailableInputDevices.add(devDesc);
273 if (index >= 0) {
274 mAvailableInputDevices[index]->mId = nextUniqueId();
275 mAvailableInputDevices[index]->mModule = module;
276 } else {
277 return NO_MEMORY;
278 }
279 } break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700280
281 // handle input device disconnection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700282 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
283 if (index < 0) {
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700284 ALOGW("setDeviceConnectionState() device not connected: %d", device);
285 return INVALID_OPERATION;
286 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700287
288 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
289
290 // Set Disconnect to HALs
291 AudioParameter param = AudioParameter(address);
292 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
293 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
294
295 checkInputsForDevice(device, state, inputs, address);
296 mAvailableInputDevices.remove(devDesc);
297
298 } break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700299
300 default:
301 ALOGE("setDeviceConnectionState() invalid state: %x", state);
302 return BAD_VALUE;
303 }
304
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700305 closeAllInputs();
306
307 if (mPhoneState == AUDIO_MODE_IN_CALL) {
308 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
309 updateCallRouting(newDevice);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700310 }
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700311
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700312 mpClientInterface->onAudioPortListUpdate();
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700313 return NO_ERROR;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700314 } // end if is input device
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700315
316 ALOGW("setDeviceConnectionState() invalid device: %x", device);
317 return BAD_VALUE;
318}
319
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700320audio_policy_dev_state_t AudioPolicyManagerCustom::getDeviceConnectionState(audio_devices_t device,
321 const char *device_address)
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700322{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700323 audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
324 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
325 devDesc->mAddress = (device_address == NULL) ? String8("") : String8(device_address);
326 ssize_t index;
327 DeviceVector *deviceVector;
328
329 if (audio_is_output_device(device)) {
330 deviceVector = &mAvailableOutputDevices;
331 } else if (audio_is_input_device(device)) {
332 deviceVector = &mAvailableInputDevices;
333 } else {
334 ALOGW("getDeviceConnectionState() invalid device type %08x", device);
335 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
336 }
337
338 index = deviceVector->indexOf(devDesc);
339 if (index >= 0) {
340 return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
341 } else {
342 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
343 }
344}
345
346void AudioPolicyManagerCustom::setPhoneState(audio_mode_t state)
347{
348 ALOGD("setPhoneState() state %d", state);
349 audio_devices_t newDevice = AUDIO_DEVICE_NONE;
350
351 if (state < 0 || state >= AUDIO_MODE_CNT) {
352 ALOGW("setPhoneState() invalid state %d", state);
353 return;
354 }
355
356 if (state == mPhoneState ) {
357 ALOGW("setPhoneState() setting same state %d", state);
358 return;
359 }
360
361 // if leaving call state, handle special case of active streams
362 // pertaining to sonification strategy see handleIncallSonification()
363 if (isInCall()) {
364 ALOGV("setPhoneState() in call state management: new state is %d", state);
365 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
366 handleIncallSonification((audio_stream_type_t)stream, false, true);
367 }
368 }
369
370 // store previous phone state for management of sonification strategy below
371 int oldState = mPhoneState;
372 mPhoneState = state;
373 bool force = false;
374
375 // are we entering or starting a call
376 if (!isStateInCall(oldState) && isStateInCall(state)) {
377 ALOGV(" Entering call in setPhoneState()");
378 // force routing command to audio hardware when starting a call
379 // even if no device change is needed
380 force = true;
381 for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
382 mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
383 sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
384 }
385 } else if (isStateInCall(oldState) && !isStateInCall(state)) {
386 ALOGV(" Exiting call in setPhoneState()");
387 // force routing command to audio hardware when exiting a call
388 // even if no device change is needed
389 force = true;
390 for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
391 mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
392 sVolumeProfiles[AUDIO_STREAM_DTMF][j];
393 }
394 } else if (isStateInCall(state) && (state != oldState)) {
395 ALOGV(" Switching between telephony and VoIP in setPhoneState()");
396 // force routing command to audio hardware when switching between telephony and VoIP
397 // even if no device change is needed
398 force = true;
399 }
400
401 // check for device and output changes triggered by new phone state
402 checkA2dpSuspend();
403 checkOutputForAllStrategies();
404 updateDevicesAndOutputs();
405
406 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
407
408#ifdef VOICE_CONCURRENCY
409 int voice_call_state = 0;
410 char propValue[PROPERTY_VALUE_MAX];
411 bool prop_playback_enabled = false, prop_rec_enabled=false, prop_voip_enabled = false;
412
413 if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
414 prop_playback_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
415 }
416
417 if(property_get("voice.record.conc.disabled", propValue, NULL)) {
418 prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
419 }
420
421 if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
422 prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
423 }
424
425 bool mode_in_call = (AUDIO_MODE_IN_CALL != oldState) && (AUDIO_MODE_IN_CALL == state);
426 //query if it is a actual voice call initiated by telephony
427 if (mode_in_call) {
428 String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0, String8("in_call"));
429 AudioParameter result = AudioParameter(valueStr);
430 if (result.getInt(String8("in_call"), voice_call_state) == NO_ERROR)
431 ALOGD("SetPhoneState: Voice call state = %d", voice_call_state);
432 }
433
434 if (mode_in_call && voice_call_state) {
435 ALOGD("Entering to call mode oldState :: %d state::%d ",oldState, state);
436 mvoice_call_state = voice_call_state;
437 if (prop_playback_enabled) {
438 //Call invalidate to reset all opened non ULL audio tracks
439 // Move tracks associated to this strategy from previous output to new output
440 for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
441 ALOGV(" Invalidate on call mode for stream :: %d ", i);
442 //FIXME see fixme on name change
443 mpClientInterface->invalidateStream((audio_stream_type_t)i);
444 }
445 }
446
447 if (prop_rec_enabled) {
448 //Close all active inputs
449 audio_io_handle_t activeInput = getActiveInput();
450 if (activeInput != 0) {
451 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
452 switch(activeDesc->mInputSource) {
453 case AUDIO_SOURCE_VOICE_UPLINK:
454 case AUDIO_SOURCE_VOICE_DOWNLINK:
455 case AUDIO_SOURCE_VOICE_CALL:
456 ALOGD("FOUND active input during call active: %d",activeDesc->mInputSource);
457 break;
458
459 case AUDIO_SOURCE_VOICE_COMMUNICATION:
460 if(prop_voip_enabled) {
461 ALOGD("CLOSING VoIP input source on call setup :%d ",activeDesc->mInputSource);
462 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
463 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
464 }
465 break;
466
467 default:
468 ALOGD("CLOSING input on call setup for inputSource: %d",activeDesc->mInputSource);
469 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
470 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
471 break;
472 }
473 }
474 } else if (prop_voip_enabled) {
475 audio_io_handle_t activeInput = getActiveInput();
476 if (activeInput != 0) {
477 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
478 if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeDesc->mInputSource) {
479 ALOGD("CLOSING VoIP on call setup : %d",activeDesc->mInputSource);
480 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
481 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
482 }
483 }
484 }
485
486 //suspend PCM (deep-buffer) output & close compress & direct tracks
487 for (size_t i = 0; i < mOutputs.size(); i++) {
488 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
489 if ( (outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
490 ALOGD("ouput desc / profile is NULL");
491 continue;
492 }
493 if (((!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY))
494 && prop_playback_enabled) {
495 ALOGD(" calling suspendOutput on call mode for primary output");
496 mpClientInterface->suspendOutput(mOutputs.keyAt(i));
497 } //Close compress all sessions
498 else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
499 && prop_playback_enabled) {
500 ALOGD(" calling closeOutput on call mode for COMPRESS output");
501 closeOutput(mOutputs.keyAt(i));
502 }
503 else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)
504 && prop_voip_enabled) {
505 ALOGD(" calling closeOutput on call mode for DIRECT output");
506 closeOutput(mOutputs.keyAt(i));
507 }
508 }
509 }
510
511 if ((AUDIO_MODE_IN_CALL == oldState || AUDIO_MODE_IN_COMMUNICATION == oldState) &&
512 (AUDIO_MODE_NORMAL == state) && prop_playback_enabled && mvoice_call_state) {
513 ALOGD("EXITING from call mode oldState :: %d state::%d \n",oldState, state);
514 mvoice_call_state = 0;
515 //restore PCM (deep-buffer) output after call termination
516 for (size_t i = 0; i < mOutputs.size(); i++) {
517 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
518 if ( (outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
519 ALOGD("ouput desc / profile is NULL");
520 continue;
521 }
522 if (!outputDesc->isDuplicated() && outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
523 ALOGD("calling restoreOutput after call mode for primary output");
524 mpClientInterface->restoreOutput(mOutputs.keyAt(i));
525 }
526 }
527 //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
528 for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
529 ALOGD("Invalidate after call ends for stream :: %d ", i);
530 //FIXME see fixme on name change
531 mpClientInterface->invalidateStream((audio_stream_type_t)i);
532 }
533 }
534#endif
535#ifdef RECORD_PLAY_CONCURRENCY
536 char recConcPropValue[PROPERTY_VALUE_MAX];
537 bool prop_rec_play_enabled = false;
538
539 if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
540 prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
541 }
542 if (prop_rec_play_enabled) {
543 if (AUDIO_MODE_IN_COMMUNICATION == mPhoneState) {
544 ALOGD("phone state changed to MODE_IN_COMM invlaidating music and voice streams");
545 // call invalidate for voice streams, so that it can use deepbuffer with VoIP out device from HAL
546 mpClientInterface->invalidateStream(AUDIO_STREAM_VOICE_CALL);
547 // call invalidate for music, so that compress will fallback to deep-buffer with VoIP out device
548 mpClientInterface->invalidateStream(AUDIO_STREAM_MUSIC);
549
550 // close compress output to make sure session will be closed before timeout(60sec)
551 for (size_t i = 0; i < mOutputs.size(); i++) {
552
553 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
554 if ((outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
555 ALOGD("ouput desc / profile is NULL");
556 continue;
557 }
558
559 if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
560 ALOGD("calling closeOutput on call mode for COMPRESS output");
561 closeOutput(mOutputs.keyAt(i));
562 }
563 }
564 } else if ((oldState == AUDIO_MODE_IN_COMMUNICATION) &&
565 (mPhoneState == AUDIO_MODE_NORMAL)) {
566 // call invalidate for music so that music can fallback to compress
567 mpClientInterface->invalidateStream(AUDIO_STREAM_MUSIC);
568 }
569 }
570#endif
571
572 mPrevPhoneState = oldState;
573
574 int delayMs = 0;
575 if (isStateInCall(state)) {
576 nsecs_t sysTime = systemTime();
577 for (size_t i = 0; i < mOutputs.size(); i++) {
578 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
579 // mute media and sonification strategies and delay device switch by the largest
580 // latency of any output where either strategy is active.
581 // This avoid sending the ring tone or music tail into the earpiece or headset.
582 if ((desc->isStrategyActive(STRATEGY_MEDIA,
583 SONIFICATION_HEADSET_MUSIC_DELAY,
584 sysTime) ||
585 desc->isStrategyActive(STRATEGY_SONIFICATION,
586 SONIFICATION_HEADSET_MUSIC_DELAY,
587 sysTime)) &&
588 (delayMs < (int)desc->mLatency*2)) {
589 delayMs = desc->mLatency*2;
590 }
591 setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
592 setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
593 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
594 setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
595 setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
596 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
597 }
598 }
599
600 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
601 // the device returned is not necessarily reachable via this output
602 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
603 // force routing command to audio hardware when ending call
604 // even if no device change is needed
605 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
606 rxDevice = hwOutputDesc->device();
607 }
608
609 if (state == AUDIO_MODE_IN_CALL) {
610 updateCallRouting(rxDevice, delayMs);
611 } else if (oldState == AUDIO_MODE_IN_CALL) {
612 if (mCallRxPatch != 0) {
613 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
614 mCallRxPatch.clear();
615 }
616 if (mCallTxPatch != 0) {
617 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
618 mCallTxPatch.clear();
619 }
620 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
621 } else {
622 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
623 }
624
625 //update device for all non-primary outputs
626 for (size_t i = 0; i < mOutputs.size(); i++) {
627 audio_io_handle_t output = mOutputs.keyAt(i);
628 if (output != mPrimaryOutput) {
629 newDevice = getNewOutputDevice(output, false /*fromCache*/);
630 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
631 }
632 }
633
634 // if entering in call state, handle special case of active streams
635 // pertaining to sonification strategy see handleIncallSonification()
636 if (isStateInCall(state)) {
637 ALOGV("setPhoneState() in call state management: new state is %d", state);
638 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
639 handleIncallSonification((audio_stream_type_t)stream, true, true);
640 }
641 }
642
643 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
644 if (state == AUDIO_MODE_RINGTONE &&
645 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
646 mLimitRingtoneVolume = true;
647 } else {
648 mLimitRingtoneVolume = false;
649 }
650}
651
652void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage,
653 audio_policy_forced_cfg_t config)
654{
655 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700656
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700657 bool forceVolumeReeval = false;
658 switch(usage) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700659 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
660 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
661 config != AUDIO_POLICY_FORCE_NONE) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700662 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
663 return;
664 }
665 forceVolumeReeval = true;
666 mForceUse[usage] = config;
667 break;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700668 case AUDIO_POLICY_FORCE_FOR_MEDIA:
669 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700670#ifdef AUDIO_EXTN_FM_ENABLED
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700671 config != AUDIO_POLICY_FORCE_SPEAKER &&
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700672#endif
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700673 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
674 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
675 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
676 config != AUDIO_POLICY_FORCE_NO_BT_A2DP) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700677 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
678 return;
679 }
680 mForceUse[usage] = config;
681 break;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700682 case AUDIO_POLICY_FORCE_FOR_RECORD:
683 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
684 config != AUDIO_POLICY_FORCE_NONE) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700685 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
686 return;
687 }
688 mForceUse[usage] = config;
689 break;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700690 case AUDIO_POLICY_FORCE_FOR_DOCK:
691 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
692 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
693 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
694 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
695 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700696 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
697 }
698 forceVolumeReeval = true;
699 mForceUse[usage] = config;
700 break;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700701 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
702 if (config != AUDIO_POLICY_FORCE_NONE &&
703 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700704 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
705 }
706 forceVolumeReeval = true;
707 mForceUse[usage] = config;
708 break;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700709 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
710 if (config != AUDIO_POLICY_FORCE_NONE &&
711 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
712 ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config);
713 }
714 mForceUse[usage] = config;
715 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700716 default:
717 ALOGW("setForceUse() invalid usage %d", usage);
718 break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700719 }
720
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700721 // check for device and output changes triggered by new force usage
722 checkA2dpSuspend();
723 checkOutputForAllStrategies();
724 updateDevicesAndOutputs();
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700725 if (mPhoneState == AUDIO_MODE_IN_CALL) {
726 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
727 updateCallRouting(newDevice);
728 }
729 for (size_t i = 0; i < mOutputs.size(); i++) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700730 audio_io_handle_t output = mOutputs.keyAt(i);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700731 audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
732 if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
733 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
734 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700735 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
736 applyStreamVolumes(output, newDevice, 0, true);
737 }
738 }
739
740 audio_io_handle_t activeInput = getActiveInput();
741 if (activeInput != 0) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700742 setInputDevice(activeInput, getNewInputDevice(activeInput));
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700743 }
744
745}
746
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700747audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
748 audio_devices_t device,
749 audio_stream_type_t stream,
750 uint32_t samplingRate,
751 audio_format_t format,
752 audio_channel_mask_t channelMask,
753 audio_output_flags_t flags,
754 const audio_offload_info_t *offloadInfo)
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700755{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700756 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
757 uint32_t latency = 0;
758 status_t status;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700759
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700760#ifdef AUDIO_POLICY_TEST
761 if (mCurOutput != 0) {
762 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
763 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
764
765 if (mTestOutputs[mCurOutput] == 0) {
766 ALOGV("getOutput() opening test output");
767 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
768 outputDesc->mDevice = mTestDevice;
769 outputDesc->mLatency = mTestLatencyMs;
770 outputDesc->mFlags =
771 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
772 outputDesc->mRefCount[stream] = 0;
773 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
774 config.sample_rate = mTestSamplingRate;
775 config.channel_mask = mTestChannels;
776 config.format = mTestFormat;
777 if (offloadInfo != NULL) {
778 config.offload_info = *offloadInfo;
779 }
780 status = mpClientInterface->openOutput(0,
781 &mTestOutputs[mCurOutput],
782 &config,
783 &outputDesc->mDevice,
784 String8(""),
785 &outputDesc->mLatency,
786 outputDesc->mFlags);
787 if (status == NO_ERROR) {
788 outputDesc->mSamplingRate = config.sample_rate;
789 outputDesc->mFormat = config.format;
790 outputDesc->mChannelMask = config.channel_mask;
791 AudioParameter outputCmd = AudioParameter();
792 outputCmd.addInt(String8("set_id"),mCurOutput);
793 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
794 addOutput(mTestOutputs[mCurOutput], outputDesc);
795 }
796 }
797 return mTestOutputs[mCurOutput];
798 }
799#endif //AUDIO_POLICY_TEST
800
801#ifdef VOICE_CONCURRENCY
802 char propValue[PROPERTY_VALUE_MAX];
803 bool prop_play_enabled=false, prop_voip_enabled = false;
804
805 if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
806 prop_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
807 }
808
809 if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
810 prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
811 }
812
813 if (prop_play_enabled && mvoice_call_state) {
814 //check if voice call is active / running in background
815 if((AUDIO_MODE_IN_CALL == mPhoneState) ||
816 ((AUDIO_MODE_IN_CALL == mPrevPhoneState)
817 && (AUDIO_MODE_IN_COMMUNICATION == mPhoneState)))
818 {
819 if(AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
820 if(prop_voip_enabled) {
821 ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
822 // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
823 return 0;
824 }
825 }
826 else {
827 ALOGD(" IN call mode adding ULL flags .. flags: %x ", flags );
828 flags = AUDIO_OUTPUT_FLAG_FAST;
829 }
830 }
831 } else if (prop_voip_enabled && mvoice_call_state) {
832 //check if voice call is active / running in background
833 //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
834 //return only ULL ouput
835 if((AUDIO_MODE_IN_CALL == mPhoneState) ||
836 ((AUDIO_MODE_IN_CALL == mPrevPhoneState)
837 && (AUDIO_MODE_IN_COMMUNICATION == mPhoneState)))
838 {
839 if(AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
840 ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
841 // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
842 return 0;
843 }
844 }
845 }
846#endif
847
848#ifdef WFD_CONCURRENCY
849 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
850 if ((availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY)
851 && (stream != AUDIO_STREAM_MUSIC)) {
852 ALOGD(" WFD mode adding ULL flags for non music stream.. flags: %x ", flags );
853 //For voip paths
854 if(flags & AUDIO_OUTPUT_FLAG_DIRECT)
855 flags = AUDIO_OUTPUT_FLAG_DIRECT;
856 else //route every thing else to ULL path
857 flags = AUDIO_OUTPUT_FLAG_FAST;
858 }
859#endif
860
861#ifdef RECORD_PLAY_CONCURRENCY
862 char recConcPropValue[PROPERTY_VALUE_MAX];
863 bool prop_rec_play_enabled = false;
864
865 if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
866 prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
867 }
868 if ((prop_rec_play_enabled) &&
869 ((true == mIsInputRequestOnProgress) || (activeInputsCount() > 0))) {
870 if (AUDIO_MODE_IN_COMMUNICATION == mPhoneState) {
871 if (AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
872 // allow VoIP using voice path
873 // Do nothing
874 } else if((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
875 ALOGD(" MODE_IN_COMM is setforcing deep buffer output for non ULL... flags: %x", flags);
876 // use deep buffer path for all non ULL outputs
877 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
878 }
879 } else if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
880 ALOGD(" Record mode is on forcing deep buffer output for non ULL... flags: %x ", flags);
881 // use deep buffer path for all non ULL outputs
882 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
883 }
884 }
885 if (prop_rec_play_enabled &&
886 (stream == AUDIO_STREAM_ENFORCED_AUDIBLE)) {
887 ALOGD("Record conc is on forcing ULL output for ENFORCED_AUDIBLE");
888 flags = AUDIO_OUTPUT_FLAG_FAST;
889 }
890#endif
891 // open a direct output if required by specified parameters
892 //force direct flag if offload flag is set: offloading implies a direct output stream
893 // and all common behaviors are driven by checking only the direct flag
894 // this should normally be set appropriately in the policy configuration file
895 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
896 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
897 }
898 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
899 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
900 }
901
902 if ((format == AUDIO_FORMAT_PCM_16_BIT) &&(popcount(channelMask) > 2)) {
903 ALOGV("owerwrite flag(%x) for PCM16 multi-channel(CM:%x) playback", flags ,channelMask);
904 flags = AUDIO_OUTPUT_FLAG_DIRECT;
905 }
906
907 sp<IOProfile> profile;
908
909 // skip direct output selection if the request can obviously be attached to a mixed output
910 // and not explicitly requested
911 if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
912 audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
913 audio_channel_count_from_out_mask(channelMask) <= 2) {
914 goto non_direct_output;
915 }
916
917 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
918 // creating an offloaded track and tearing it down immediately after start when audioflinger
919 // detects there is an active non offloadable effect.
920 // FIXME: We should check the audio session here but we do not have it in this context.
921 // This may prevent offloading in rare situations where effects are left active by apps
922 // in the background.
923
924 if ((((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
925 !isNonOffloadableEffectEnabled()) &&
926 flags & AUDIO_OUTPUT_FLAG_DIRECT) {
927 profile = getProfileForDirectOutput(device,
928 samplingRate,
929 format,
930 channelMask,
931 (audio_output_flags_t)flags);
932 }
933
934 if (profile != 0) {
935 sp<AudioOutputDescriptor> outputDesc = NULL;
936
937 for (size_t i = 0; i < mOutputs.size(); i++) {
938 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
939 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
940 outputDesc = desc;
941 // reuse direct output if currently open and configured with same parameters
942 if ((samplingRate == outputDesc->mSamplingRate) &&
943 (format == outputDesc->mFormat) &&
944 (channelMask == outputDesc->mChannelMask)) {
945 outputDesc->mDirectOpenCount++;
946 ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
947 return mOutputs.keyAt(i);
948 }
949 }
950 }
951 // close direct output if currently open and configured with different parameters
952 if (outputDesc != NULL) {
953 closeOutput(outputDesc->mIoHandle);
954 }
955 outputDesc = new AudioOutputDescriptor(profile);
956 outputDesc->mDevice = device;
957 outputDesc->mLatency = 0;
958 outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
959 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
960 config.sample_rate = samplingRate;
961 config.channel_mask = channelMask;
962 config.format = format;
963 if (offloadInfo != NULL) {
964 config.offload_info = *offloadInfo;
965 }
966 status = mpClientInterface->openOutput(profile->mModule->mHandle,
967 &output,
968 &config,
969 &outputDesc->mDevice,
970 String8(""),
971 &outputDesc->mLatency,
972 outputDesc->mFlags);
973
974 // only accept an output with the requested parameters
975 if (status != NO_ERROR ||
976 (samplingRate != 0 && samplingRate != config.sample_rate) ||
977 (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
978 (channelMask != 0 && channelMask != config.channel_mask)) {
979 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
980 "format %d %d, channelMask %04x %04x", output, samplingRate,
981 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
982 outputDesc->mChannelMask);
983 if (output != AUDIO_IO_HANDLE_NONE) {
984 mpClientInterface->closeOutput(output);
985 }
986 return AUDIO_IO_HANDLE_NONE;
987 }
988 outputDesc->mSamplingRate = config.sample_rate;
989 outputDesc->mChannelMask = config.channel_mask;
990 outputDesc->mFormat = config.format;
991 outputDesc->mRefCount[stream] = 0;
992 outputDesc->mStopTime[stream] = 0;
993 outputDesc->mDirectOpenCount = 1;
994
995 audio_io_handle_t srcOutput = getOutputForEffect();
996 addOutput(output, outputDesc);
997 audio_io_handle_t dstOutput = getOutputForEffect();
998 if (dstOutput == output) {
999 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
1000 }
1001 mPreviousOutputs = mOutputs;
1002 ALOGV("getOutput() returns new direct output %d", output);
1003 mpClientInterface->onAudioPortListUpdate();
1004 return output;
1005 }
1006
1007non_direct_output:
1008
1009 // ignoring channel mask due to downmix capability in mixer
1010
1011 // open a non direct output
1012
1013 // for non direct outputs, only PCM is supported
1014 if (audio_is_linear_pcm(format)) {
1015 // get which output is suitable for the specified stream. The actual
1016 // routing change will happen when startOutput() will be called
1017 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1018
1019 // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
1020 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
1021 output = selectOutput(outputs, flags, format);
1022 }
1023 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1024 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1025
1026 ALOGV("getOutput() returns output %d", output);
1027
1028 return output;
1029}
1030
1031
1032status_t AudioPolicyManagerCustom::stopOutput(audio_io_handle_t output,
1033 audio_stream_type_t stream,
1034 int session)
1035{
1036 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1037 ssize_t index = mOutputs.indexOfKey(output);
1038 if (index < 0) {
1039 ALOGW("stopOutput() unknown output %d", output);
1040 return BAD_VALUE;
1041 }
1042
1043 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1044
1045 // handle special case for sonification while in call
1046 if ((isInCall()) && (outputDesc->mRefCount[stream] == 1)) {
1047 handleIncallSonification(stream, false, false);
1048 }
1049
1050 if (outputDesc->mRefCount[stream] > 0) {
1051 // decrement usage count of this stream on the output
1052 outputDesc->changeRefCount(stream, -1);
1053 // store time at which the stream was stopped - see isStreamActive()
1054 if (outputDesc->mRefCount[stream] == 0) {
1055 outputDesc->mStopTime[stream] = systemTime();
1056 audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
1057 // delay the device switch by twice the latency because stopOutput() is executed when
1058 // the track stop() command is received and at that time the audio track buffer can
1059 // still contain data that needs to be drained. The latency only covers the audio HAL
1060 // and kernel buffers. Also the latency does not always include additional delay in the
1061 // audio path (audio DSP, CODEC ...)
1062 setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
1063
1064 // force restoring the device selection on other active outputs if it differs from the
1065 // one being selected for this output
1066 for (size_t i = 0; i < mOutputs.size(); i++) {
1067 audio_io_handle_t curOutput = mOutputs.keyAt(i);
1068 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1069 if (curOutput != output &&
1070 desc->isActive() &&
1071 outputDesc->sharesHwModuleWith(desc) &&
1072 (newDevice != desc->device())) {
1073 setOutputDevice(curOutput,
1074 getNewOutputDevice(curOutput, false /*fromCache*/),
1075 true,
1076 outputDesc->mLatency*2);
1077 }
1078 }
1079 // update the outputs if stopping one with a stream that can affect notification routing
1080 handleNotificationRoutingForStream(stream);
1081 }
1082 return NO_ERROR;
1083 } else {
1084 ALOGW("stopOutput() refcount is already 0 for output %d", output);
1085 return INVALID_OPERATION;
1086 }
1087}
1088
1089audio_io_handle_t AudioPolicyManagerCustom::getInput(audio_source_t inputSource,
1090 uint32_t samplingRate,
1091 audio_format_t format,
1092 audio_channel_mask_t channelMask,
1093 audio_session_t session,
1094 audio_input_flags_t flags)
1095{
1096 ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
1097 "flags %#x",
1098 inputSource, samplingRate, format, channelMask, session, flags);
1099
1100 audio_devices_t device = getDeviceForInputSource(inputSource);
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001101
1102 if (device == AUDIO_DEVICE_NONE) {
1103 ALOGW("getInput() could not find device for inputSource %d", inputSource);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001104 return AUDIO_IO_HANDLE_NONE;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001105 }
1106
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001107 /*The below code is intentionally not ported.
1108 It's not needed to update the channel mask based on source because
1109 the source is sent to audio HAL through set_parameters().
1110 For example, if source = VOICE_CALL, does not mean we need to capture two channels.
1111 If the sound recorder app selects AMR as encoding format but source as RX+TX,
1112 we need both in ONE channel. So we use the channels set by the app and use source
1113 to tell the driver what needs to captured (RX only, TX only, or RX+TX ).*/
1114 // adapt channel selection to input source
1115 /*switch (inputSource) {
1116 case AUDIO_SOURCE_VOICE_UPLINK:
1117 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
1118 break;
1119 case AUDIO_SOURCE_VOICE_DOWNLINK:
1120 channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
1121 break;
1122 case AUDIO_SOURCE_VOICE_CALL:
1123 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
1124 break;
1125 default:
1126 break;
1127 }*/
1128
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001129#ifdef VOICE_CONCURRENCY
1130
1131 char propValue[PROPERTY_VALUE_MAX];
1132 bool prop_rec_enabled=false, prop_voip_enabled = false;
1133
1134 if(property_get("voice.record.conc.disabled", propValue, NULL)) {
1135 prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1136 }
1137
1138 if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
1139 prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1140 }
1141
1142 if (prop_rec_enabled && mvoice_call_state) {
1143 //check if voice call is active / running in background
1144 //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
1145 //Need to block input request
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001146 if((AUDIO_MODE_IN_CALL == mPhoneState) ||
1147 ((AUDIO_MODE_IN_CALL == mPrevPhoneState) &&
1148 (AUDIO_MODE_IN_COMMUNICATION == mPhoneState)))
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001149 {
1150 switch(inputSource) {
1151 case AUDIO_SOURCE_VOICE_UPLINK:
1152 case AUDIO_SOURCE_VOICE_DOWNLINK:
1153 case AUDIO_SOURCE_VOICE_CALL:
1154 ALOGD("Creating input during incall mode for inputSource: %d ",inputSource);
1155 break;
1156
1157 case AUDIO_SOURCE_VOICE_COMMUNICATION:
1158 if(prop_voip_enabled) {
1159 ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
1160 return 0;
1161 }
1162 break;
1163 default:
1164 ALOGD("BLOCKING input during incall mode for inputSource: %d ",inputSource);
1165 return 0;
1166 }
1167 }
1168 }//check for VoIP flag
1169 else if(prop_voip_enabled && mvoice_call_state) {
1170 //check if voice call is active / running in background
1171 //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
1172 //Need to block input request
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001173 if((AUDIO_MODE_IN_CALL == mPhoneState) ||
1174 ((AUDIO_MODE_IN_CALL == mPrevPhoneState) &&
1175 (AUDIO_MODE_IN_COMMUNICATION == mPhoneState)))
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001176 {
1177 if(inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1178 ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
1179 return 0;
1180 }
1181 }
1182 }
1183
1184#endif
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001185
1186 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
1187 bool isSoundTrigger = false;
1188 audio_source_t halInputSource = inputSource;
1189 if (inputSource == AUDIO_SOURCE_HOTWORD) {
1190 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1191 if (index >= 0) {
1192 input = mSoundTriggerSessions.valueFor(session);
1193 isSoundTrigger = true;
1194 flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1195 ALOGV("SoundTrigger capture on session %d input %d", session, input);
1196 } else {
1197 halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
1198 }
1199 }
1200
1201 sp<IOProfile> profile = getInputProfile(device,
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001202 samplingRate,
1203 format,
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001204 channelMask,
1205 flags);
1206 if (profile == 0) {
1207 //retry without flags
1208 audio_input_flags_t log_flags = flags;
1209 flags = AUDIO_INPUT_FLAG_NONE;
1210 profile = getInputProfile(device,
1211 samplingRate,
1212 format,
1213 channelMask,
1214 flags);
1215 if (profile == 0) {
1216 ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, "
1217 "channelMask 0x%X, flags %#x",
1218 device, samplingRate, format, channelMask, log_flags);
1219 return AUDIO_IO_HANDLE_NONE;
1220 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001221 }
1222
1223 if (profile->mModule->mHandle == 0) {
1224 ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001225 return AUDIO_IO_HANDLE_NONE;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001226 }
1227
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001228 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1229 config.sample_rate = samplingRate;
1230 config.channel_mask = channelMask;
1231 config.format = format;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001232
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001233 status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
1234 &input,
1235 &config,
1236 &device,
1237 String8(""),
1238 halInputSource,
1239 flags);
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001240
1241 // only accept input with the exact requested set of parameters
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001242 if (status != NO_ERROR ||
1243 (samplingRate != config.sample_rate) ||
1244 (format != config.format) ||
1245 (channelMask != config.channel_mask)) {
1246 ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001247 samplingRate, format, channelMask);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001248 if (input != AUDIO_IO_HANDLE_NONE) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001249 mpClientInterface->closeInput(input);
1250 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001251 return AUDIO_IO_HANDLE_NONE;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001252 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001253
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001254 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
1255 inputDesc->mInputSource = inputSource;
1256 inputDesc->mRefCount = 0;
1257 inputDesc->mOpenRefCount = 1;
1258 inputDesc->mSamplingRate = samplingRate;
1259 inputDesc->mFormat = format;
1260 inputDesc->mChannelMask = channelMask;
1261 inputDesc->mDevice = device;
1262 inputDesc->mSessions.add(session);
1263 inputDesc->mIsSoundTrigger = isSoundTrigger;
1264
1265 addInput(input, inputDesc);
1266 mpClientInterface->onAudioPortListUpdate();
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001267 return input;
1268}
1269
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001270status_t AudioPolicyManagerCustom::startInput(audio_io_handle_t input,
1271 audio_session_t session)
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001272{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001273 ALOGV("startInput() input %d", input);
1274 ssize_t index = mInputs.indexOfKey(input);
Zhou Songc0d78c22014-06-16 10:48:22 +08001275 if (index < 0) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001276 ALOGW("startInput() unknown input %d", input);
1277 return BAD_VALUE;
1278 }
1279 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1280
1281 index = inputDesc->mSessions.indexOf(session);
1282 if (index < 0) {
1283 ALOGW("startInput() unknown session %d on input %d", session, input);
Zhou Songc0d78c22014-06-16 10:48:22 +08001284 return BAD_VALUE;
1285 }
1286
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001287 // virtual input devices are compatible with other input devices
1288 if (!isVirtualInputDevice(inputDesc->mDevice)) {
Zhou Songc0d78c22014-06-16 10:48:22 +08001289
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001290 // for a non-virtual input device, check if there is another (non-virtual) active input
1291 audio_io_handle_t activeInput = getActiveInput();
1292 if (activeInput != 0 && activeInput != input) {
Zhou Songc0d78c22014-06-16 10:48:22 +08001293
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001294 // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1295 // otherwise the active input continues and the new input cannot be started.
1296 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
1297 if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
1298 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
1299 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
1300 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
1301 } else {
1302 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
1303 return INVALID_OPERATION;
Zhou Songc0d78c22014-06-16 10:48:22 +08001304 }
Zhou Songc0d78c22014-06-16 10:48:22 +08001305 }
Zhou Songc0d78c22014-06-16 10:48:22 +08001306 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001307
1308#ifdef RECORD_PLAY_CONCURRENCY
1309 mIsInputRequestOnProgress = true;
1310
1311 char getPropValue[PROPERTY_VALUE_MAX];
1312 bool prop_rec_play_enabled = false;
1313
1314 if (property_get("rec.playback.conc.disabled", getPropValue, NULL)) {
1315 prop_rec_play_enabled = atoi(getPropValue) || !strncmp("true", getPropValue, 4);
1316 }
1317
1318 if ((prop_rec_play_enabled) &&(activeInputsCount() == 0)){
1319 // send update to HAL on record playback concurrency
1320 AudioParameter param = AudioParameter();
1321 param.add(String8("rec_play_conc_on"), String8("true"));
1322 ALOGD("startInput() setParameters rec_play_conc is setting to ON ");
1323 mpClientInterface->setParameters(0, param.toString());
1324
1325 // Call invalidate to reset all opened non ULL audio tracks
1326 // Move tracks associated to this strategy from previous output to new output
1327 for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
1328 // Do not call invalidate for ENFORCED_AUDIBLE (otherwise pops are seen for camcorder)
1329 if (i != AUDIO_STREAM_ENFORCED_AUDIBLE) {
1330 ALOGD("Invalidate on releaseInput for stream :: %d ", i);
1331 //FIXME see fixme on name change
1332 mpClientInterface->invalidateStream((audio_stream_type_t)i);
1333 }
1334 }
1335 // close compress tracks
1336 for (size_t i = 0; i < mOutputs.size(); i++) {
1337 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
1338 if ((outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
1339 ALOGD("ouput desc / profile is NULL");
1340 continue;
1341 }
1342 if (outputDesc->mProfile->mFlags
1343 & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
1344 // close compress sessions
1345 ALOGD("calling closeOutput on record conc for COMPRESS output");
1346 closeOutput(mOutputs.keyAt(i));
1347 }
1348 }
1349 }
1350#endif
1351
1352 if (inputDesc->mRefCount == 0) {
1353 if (activeInputsCount() == 0) {
1354 SoundTrigger::setCaptureState(true);
1355 }
1356 setInputDevice(input, getNewInputDevice(input), true /* force */);
1357
1358 // Automatically enable the remote submix output when input is started.
1359 // For remote submix (a virtual device), we open only one input per capture request.
1360 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1361 setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1362 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1363 }
1364 }
1365
1366 ALOGV("AudioPolicyManagerCustom::startInput() input source = %d", inputDesc->mInputSource);
1367
1368 inputDesc->mRefCount++;
1369#ifdef RECORD_PLAY_CONCURRENCY
1370 mIsInputRequestOnProgress = false;
1371#endif
1372 return NO_ERROR;
Zhou Songc0d78c22014-06-16 10:48:22 +08001373}
1374
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001375status_t AudioPolicyManagerCustom::stopInput(audio_io_handle_t input,
1376 audio_session_t session)
1377{
1378 ALOGV("stopInput() input %d", input);
1379 ssize_t index = mInputs.indexOfKey(input);
1380 if (index < 0) {
1381 ALOGW("stopInput() unknown input %d", input);
1382 return BAD_VALUE;
Zhou Songc0d78c22014-06-16 10:48:22 +08001383 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001384 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1385
1386 index = inputDesc->mSessions.indexOf(session);
1387 if (index < 0) {
1388 ALOGW("stopInput() unknown session %d on input %d", session, input);
1389 return BAD_VALUE;
1390 }
1391
1392 if (inputDesc->mRefCount == 0) {
1393 ALOGW("stopInput() input %d already stopped", input);
1394 return INVALID_OPERATION;
1395 }
1396
1397 inputDesc->mRefCount--;
1398 if (inputDesc->mRefCount == 0) {
1399
1400 // automatically disable the remote submix output when input is stopped
1401 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1402 setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1403 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1404 }
1405
1406 resetInputDevice(input);
1407
1408 if (activeInputsCount() == 0) {
1409 SoundTrigger::setCaptureState(false);
1410 }
1411 }
1412
1413#ifdef RECORD_PLAY_CONCURRENCY
1414 char propValue[PROPERTY_VALUE_MAX];
1415 bool prop_rec_play_enabled = false;
1416
1417 if (property_get("rec.playback.conc.disabled", propValue, NULL)) {
1418 prop_rec_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1419 }
1420
1421 if ((prop_rec_play_enabled) && (activeInputsCount() == 0)) {
1422
1423 //send update to HAL on record playback concurrency
1424 AudioParameter param = AudioParameter();
1425 param.add(String8("rec_play_conc_on"), String8("false"));
1426 ALOGD("stopInput() setParameters rec_play_conc is setting to OFF ");
1427 mpClientInterface->setParameters(0, param.toString());
1428
1429 //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
1430 for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
1431 //Do not call invalidate for ENFORCED_AUDIBLE (otherwise pops are seen for camcorder stop tone)
1432 if (i != AUDIO_STREAM_ENFORCED_AUDIBLE) {
1433 ALOGD(" Invalidate on stopInput for stream :: %d ", i);
1434 //FIXME see fixme on name change
1435 mpClientInterface->invalidateStream((audio_stream_type_t)i);
1436 }
1437 }
1438 }
1439#endif
1440 return NO_ERROR;
1441}
1442
1443status_t AudioPolicyManagerCustom::setStreamVolumeIndex(audio_stream_type_t stream,
1444 int index,
1445 audio_devices_t device)
1446{
1447
1448 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1449 return BAD_VALUE;
1450 }
1451 if (!audio_is_output_device(device)) {
1452 return BAD_VALUE;
1453 }
1454
1455 // Force max volume if stream cannot be muted
1456 if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
1457
1458 ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1459 stream, device, index);
1460
1461 // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1462 // clear all device specific values
1463 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1464 mStreams[stream].mIndexCur.clear();
1465 }
1466 mStreams[stream].mIndexCur.add(device, index);
1467
1468 // compute and apply stream volume on all outputs according to connected device
1469 status_t status = NO_ERROR;
1470 for (size_t i = 0; i < mOutputs.size(); i++) {
1471 audio_devices_t curDevice =
1472 getDeviceForVolume(mOutputs.valueAt(i)->device());
1473#ifdef AUDIO_EXTN_FM_ENABLED
1474 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
1475 if (((device == AUDIO_DEVICE_OUT_DEFAULT) &&
1476 ((availableOutputDeviceTypes & AUDIO_DEVICE_OUT_FM) != AUDIO_DEVICE_OUT_FM)) ||
1477 (device == curDevice)) {
1478#else
1479 if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
1480#endif
1481 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1482 if (volStatus != NO_ERROR) {
1483 status = volStatus;
1484 }
1485 }
1486 }
1487 return status;
Zhou Songc0d78c22014-06-16 10:48:22 +08001488}
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001489
1490// This function checks for the parameters which can be offloaded.
1491// This can be enhanced depending on the capability of the DSP and policy
1492// of the system.
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001493bool AudioPolicyManagerCustom::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001494{
1495 ALOGD("copl: isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
1496 " BitRate=%u, duration=%lld us, has_video=%d",
1497 offloadInfo.sample_rate, offloadInfo.channel_mask,
1498 offloadInfo.format,
1499 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
1500 offloadInfo.has_video);
1501
1502#ifdef VOICE_CONCURRENCY
1503 char concpropValue[PROPERTY_VALUE_MAX];
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001504 if (property_get("voice.playback.conc.disabled", concpropValue, NULL)) {
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001505 bool propenabled = atoi(concpropValue) || !strncmp("true", concpropValue, 4);
1506 if (propenabled) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001507 if (isInCall())
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001508 {
1509 ALOGD("\n copl: blocking compress offload on call mode\n");
1510 return false;
1511 }
1512 }
1513 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001514#endif
1515#ifdef RECORD_PLAY_CONCURRENCY
1516 char recConcPropValue[PROPERTY_VALUE_MAX];
1517 bool prop_rec_play_enabled = false;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001518
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001519 if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
1520 prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
1521 }
1522
1523 if ((prop_rec_play_enabled) &&
1524 ((true == mIsInputRequestOnProgress) || (activeInputsCount() > 0))) {
1525 ALOGD("copl: blocking compress offload for record concurrency");
1526 return false;
1527 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001528#endif
1529 // Check if stream type is music, then only allow offload as of now.
1530 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
1531 {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001532 ALOGD("isOffloadSupported: stream_type != MUSIC, returning false");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001533 return false;
1534 }
1535
1536 char propValue[PROPERTY_VALUE_MAX];
1537 bool pcmOffload = false;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001538#ifdef PCM_OFFLOAD_ENABLED
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001539 if (audio_is_offload_pcm(offloadInfo.format)) {
1540 if(property_get("audio.offload.pcm.enable", propValue, NULL)) {
1541 bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1542 if (prop_enabled) {
1543 ALOGW("PCM offload property is enabled");
1544 pcmOffload = true;
1545 }
1546 }
1547 if (!pcmOffload) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001548 ALOGD("PCM offload disabled by property audio.offload.pcm.enable");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001549 return false;
1550 }
1551 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001552#endif
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001553
1554 if (!pcmOffload) {
1555 // Check if offload has been disabled
1556 if (property_get("audio.offload.disable", propValue, "0")) {
1557 if (atoi(propValue) != 0) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001558 ALOGD("offload disabled by audio.offload.disable=%s", propValue );
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001559 return false;
1560 }
1561 }
1562
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05301563 //check if it's multi-channel AAC (includes sub formats), FLAC and VORBIS format
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001564 if ((popcount(offloadInfo.channel_mask) > 2) &&
1565 (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05301566 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
1567 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS))) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001568 ALOGD("offload disabled for multi-channel AAC and FLAC format");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001569 return false;
1570 }
1571
1572 if (offloadInfo.has_video)
1573 {
1574 if(property_get("av.offload.enable", propValue, NULL)) {
1575 bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1576 if (!prop_enabled) {
1577 ALOGW("offload disabled by av.offload.enable = %s ", propValue );
1578 return false;
1579 }
1580 } else {
1581 return false;
1582 }
1583
1584 if(offloadInfo.is_streaming) {
1585 if (property_get("av.streaming.offload.enable", propValue, NULL)) {
1586 bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1587 if (!prop_enabled) {
1588 ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
1589 return false;
1590 }
1591 } else {
1592 //Do not offload AV streamnig if the property is not defined
1593 return false;
1594 }
1595 }
1596 ALOGD("copl: isOffloadSupported: has_video == true, property\
1597 set to enable offload");
1598 }
1599 }
1600
1601 //If duration is less than minimum value defined in property, return false
1602 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1603 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1604 ALOGD("copl: Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1605 return false;
1606 }
1607 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1608 ALOGD("copl: Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05301609 //duration checks only valid for MP3/AAC/VORBIS/WMA/ALAC/APE formats,
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001610 //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001611 if ((offloadInfo.format == AUDIO_FORMAT_MP3) ||
1612 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
1613 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05301614 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS) ||
Weiyin Jiang16cd2422015-05-06 20:32:06 +08001615 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) ||
1616 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) ||
Satya Krishna Pindiproli70471602015-04-24 19:12:43 +05301617 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_ALAC) ||
1618 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_APE) ||
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001619 pcmOffload)
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001620 return false;
1621 }
1622
1623 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1624 // creating an offloaded track and tearing it down immediately after start when audioflinger
1625 // detects there is an active non offloadable effect.
1626 // FIXME: We should check the audio session here but we do not have it in this context.
1627 // This may prevent offloading in rare situations where effects are left active by apps
1628 // in the background.
1629 if (isNonOffloadableEffectEnabled()) {
1630 return false;
1631 }
1632
1633 // See if there is a profile to support this.
1634 // AUDIO_DEVICE_NONE
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001635 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001636 offloadInfo.sample_rate,
1637 offloadInfo.format,
1638 offloadInfo.channel_mask,
1639 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001640 ALOGD("copl: isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
1641 return (profile != 0);
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001642}
1643
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001644uint32_t AudioPolicyManagerCustom::nextUniqueId()
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001645{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001646 return android_atomic_inc(&mNextUniqueId);
1647}
1648
1649AudioPolicyManagerCustom::routing_strategy AudioPolicyManagerCustom::getStrategy(
1650 audio_stream_type_t stream) {
1651 // stream to strategy mapping
1652 switch (stream) {
1653 case AUDIO_STREAM_VOICE_CALL:
1654 case AUDIO_STREAM_BLUETOOTH_SCO:
1655 return STRATEGY_PHONE;
1656 case AUDIO_STREAM_RING:
1657 case AUDIO_STREAM_ALARM:
1658 return STRATEGY_SONIFICATION;
1659 case AUDIO_STREAM_NOTIFICATION:
1660 return STRATEGY_SONIFICATION_RESPECTFUL;
1661 case AUDIO_STREAM_DTMF:
1662 return STRATEGY_DTMF;
1663 default:
1664 ALOGE("unknown stream type");
1665 case AUDIO_STREAM_SYSTEM:
1666 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1667 // while key clicks are played produces a poor result
1668 case AUDIO_STREAM_TTS:
1669 case AUDIO_STREAM_MUSIC:
1670#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
1671 case AUDIO_STREAM_INCALL_MUSIC:
1672#endif
1673 return STRATEGY_MEDIA;
1674 case AUDIO_STREAM_ENFORCED_AUDIBLE:
1675 return STRATEGY_ENFORCED_AUDIBLE;
Naresh Tanniru36c08932014-01-27 18:40:53 +05301676 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001677}
Naresh Tanniru36c08932014-01-27 18:40:53 +05301678
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001679void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
1680 switch(stream) {
1681 case AUDIO_STREAM_MUSIC:
1682 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
1683 updateDevicesAndOutputs();
1684 break;
1685 default:
1686 break;
Naresh Tanniru36c08932014-01-27 18:40:53 +05301687 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001688}
Naresh Tanniru36c08932014-01-27 18:40:53 +05301689
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001690audio_devices_t AudioPolicyManagerCustom::getDeviceForStrategy(routing_strategy strategy,
1691 bool fromCache)
1692{
1693 uint32_t device = AUDIO_DEVICE_NONE;
1694
1695 if (fromCache) {
1696 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
1697 strategy, mDeviceForStrategy[strategy]);
1698 return mDeviceForStrategy[strategy];
Naresh Tanniru36c08932014-01-27 18:40:53 +05301699 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001700 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
1701 switch (strategy) {
Naresh Tanniru36c08932014-01-27 18:40:53 +05301702
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001703 case STRATEGY_SONIFICATION_RESPECTFUL:
1704 if (isInCall()) {
1705 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1706 } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
1707 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
1708 // while media is playing on a remote device, use the the sonification behavior.
1709 // Note that we test this usecase before testing if media is playing because
1710 // the isStreamActive() method only informs about the activity of a stream, not
1711 // if it's for local playback. Note also that we use the same delay between both tests
1712 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1713 //user "safe" speaker if available instead of normal speaker to avoid triggering
1714 //other acoustic safety mechanisms for notification
1715 if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
1716 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
1717 } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
1718 // while media is playing (or has recently played), use the same device
1719 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1720 } else {
1721 // when media is not playing anymore, fall back on the sonification behavior
1722 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1723 //user "safe" speaker if available instead of normal speaker to avoid triggering
1724 //other acoustic safety mechanisms for notification
1725 if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
1726 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001727 }
1728
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001729 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001730
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001731 case STRATEGY_DTMF:
1732 if (!isInCall()) {
1733 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1734 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1735 break;
1736 }
1737 // when in call, DTMF and PHONE strategies follow the same rules
1738 // FALL THROUGH
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001739
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001740 case STRATEGY_PHONE:
1741 // Force use of only devices on primary output if:
1742 // - in call AND
1743 // - cannot route from voice call RX OR
1744 // - audio HAL version is < 3.0 and TX device is on the primary HW module
1745 if (mPhoneState == AUDIO_MODE_IN_CALL) {
1746 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
1747 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
1748 if (((mAvailableInputDevices.types() &
1749 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
1750 (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) &&
1751 (hwOutputDesc->getAudioPort()->mModule->mHalVersion <
1752 AUDIO_DEVICE_API_VERSION_3_0))) {
1753 availableOutputDeviceTypes = availablePrimaryOutputDevices();
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001754 }
1755 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001756 // for phone strategy, we first consider the forced use and then the available devices by order
1757 // of priority
1758 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
1759 case AUDIO_POLICY_FORCE_BT_SCO:
1760 if (!isInCall() || strategy != STRATEGY_DTMF) {
1761 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1762 if (device) break;
1763 }
1764 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1765 if (device) break;
1766 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
1767 if (device) break;
1768 // if SCO device is requested but no SCO device is available, fall back to default case
1769 // FALL THROUGH
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001770
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001771 default: // FORCE_NONE
1772 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
1773 if (!isInCall() &&
1774 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1775 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1776 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1777 if (device) break;
1778 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1779 if (device) break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001780 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001781 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1782 if (device) break;
1783 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1784 if (device) break;
1785 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1786 if (device) break;
1787 if (mPhoneState != AUDIO_MODE_IN_CALL) {
1788 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1789 if (device) break;
1790 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1791 if (device) break;
1792 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1793 if (device) break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001794 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001795
1796 // Allow voice call on USB ANLG DOCK headset
1797 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1798 if (device) break;
1799
1800 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
1801 if (device) break;
1802 device = mDefaultOutputDevice->mDeviceType;
1803 if (device == AUDIO_DEVICE_NONE) {
1804 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
1805 }
1806 break;
1807
1808 case AUDIO_POLICY_FORCE_SPEAKER:
1809 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
1810 // A2DP speaker when forcing to speaker output
1811 if (!isInCall() &&
1812 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1813 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1814 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1815 if (device) break;
1816 }
1817 if (mPhoneState != AUDIO_MODE_IN_CALL) {
1818 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1819 if (device) break;
1820 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1821 if (device) break;
1822 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1823 if (device) break;
1824 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1825 if (device) break;
1826 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1827 if (device) break;
1828 }
1829 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
1830 if (device) break;
1831 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1832 if (device) break;
1833 device = mDefaultOutputDevice->mDeviceType;
1834 if (device == AUDIO_DEVICE_NONE) {
1835 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
1836 }
1837 break;
1838 }
1839
1840 if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
1841 // when in call, get the device for Phone strategy
1842 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1843 break;
1844 }
1845
1846#ifdef AUDIO_EXTN_FM_ENABLED
1847 if (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_FM) {
1848 if (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER) {
1849 device = AUDIO_DEVICE_OUT_SPEAKER;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001850 }
1851 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001852#endif
1853 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001854
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001855 case STRATEGY_SONIFICATION:
1856
1857 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1858 // handleIncallSonification().
1859 if (isInCall()) {
1860 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1861 break;
1862 }
1863 // FALL THROUGH
1864
1865 case STRATEGY_ENFORCED_AUDIBLE:
1866 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
1867 // except:
1868 // - when in call where it doesn't default to STRATEGY_PHONE behavior
1869 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
1870
1871 if ((strategy == STRATEGY_SONIFICATION) ||
1872 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
1873 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1874 if (device == AUDIO_DEVICE_NONE) {
1875 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001876 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001877 }
1878 // The second device used for sonification is the same as the device used by media strategy
1879 // FALL THROUGH
1880
1881 case STRATEGY_MEDIA: {
1882 uint32_t device2 = AUDIO_DEVICE_NONE;
1883
1884 if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
1885 // when in call, get the device for Phone strategy
1886 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1887 break;
1888 }
1889#ifdef AUDIO_EXTN_FM_ENABLED
1890 if (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER) {
1891 device = AUDIO_DEVICE_OUT_SPEAKER;
1892 break;
1893 }
1894#endif
1895
1896 if (strategy != STRATEGY_SONIFICATION) {
1897 // no sonification on remote submix (e.g. WFD)
1898 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1899 }
1900 if ((device2 == AUDIO_DEVICE_NONE) &&
1901 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1902 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1903 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1904 if (device2 == AUDIO_DEVICE_NONE) {
1905 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001906 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001907 if (device2 == AUDIO_DEVICE_NONE) {
1908 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1909 }
1910 }
1911 if (device2 == AUDIO_DEVICE_NONE) {
1912 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1913 }
1914 if ((device2 == AUDIO_DEVICE_NONE)) {
1915 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
1916 }
1917 if (device2 == AUDIO_DEVICE_NONE) {
1918 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1919 }
1920 if (device2 == AUDIO_DEVICE_NONE) {
1921 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1922 }
1923 if (device2 == AUDIO_DEVICE_NONE) {
1924 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1925 }
1926 if (device2 == AUDIO_DEVICE_NONE) {
1927 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1928 }
1929 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1930 && (device2 == AUDIO_DEVICE_NONE)) {
1931 // no sonification on aux digital (e.g. HDMI)
1932 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1933 }
1934 if ((device2 == AUDIO_DEVICE_NONE) &&
1935 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)
1936 && (strategy != STRATEGY_SONIFICATION)) {
1937 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1938 }
1939#ifdef AUDIO_EXTN_FM_ENABLED
1940 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1941 && (device2 == AUDIO_DEVICE_NONE)) {
1942 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_FM_TX;
1943 }
1944#endif
1945#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
1946 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1947 && (device2 == AUDIO_DEVICE_NONE)) {
1948 // no sonification on WFD sink
1949 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY;
1950 }
1951#endif
1952 if (device2 == AUDIO_DEVICE_NONE) {
1953 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1954 }
1955 int device3 = AUDIO_DEVICE_NONE;
1956 if (strategy == STRATEGY_MEDIA) {
1957 // ARC, SPDIF and AUX_LINE can co-exist with others.
1958 device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC;
1959 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF);
1960 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE);
1961 }
1962
1963 device2 |= device3;
1964 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
1965 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
1966 device |= device2;
1967
1968 // If hdmi system audio mode is on, remove speaker out of output list.
1969 if ((strategy == STRATEGY_MEDIA) &&
1970 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
1971 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
1972 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
1973 }
1974
1975 if (device) break;
1976 device = mDefaultOutputDevice->mDeviceType;
1977 if (device == AUDIO_DEVICE_NONE) {
1978 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
1979 }
1980 } break;
1981
1982 default:
1983 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1984 break;
1985 }
1986
1987 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1988 return device;
1989}
1990
1991audio_devices_t AudioPolicyManagerCustom::getDeviceForInputSource(audio_source_t inputSource)
1992{
1993 uint32_t device = AUDIO_DEVICE_NONE;
1994 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
1995 ~AUDIO_DEVICE_BIT_IN;
1996 switch (inputSource) {
1997 case AUDIO_SOURCE_VOICE_UPLINK:
1998 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
1999 device = AUDIO_DEVICE_IN_VOICE_CALL;
2000 break;
2001 }
2002 break;
2003
2004 case AUDIO_SOURCE_DEFAULT:
2005 case AUDIO_SOURCE_MIC:
2006 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
2007 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
2008 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2009 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2010 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2011 device = AUDIO_DEVICE_IN_USB_DEVICE;
2012 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2013 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2014 }
2015 break;
2016
2017 case AUDIO_SOURCE_VOICE_COMMUNICATION:
2018 // Allow only use of devices on primary input if in call and HAL does not support routing
2019 // to voice call path.
2020 if ((mPhoneState == AUDIO_MODE_IN_CALL) &&
2021 (mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
2022 availableDeviceTypes = availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN;
2023 }
2024
2025 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
2026 case AUDIO_POLICY_FORCE_BT_SCO:
2027 // if SCO device is requested but no SCO device is available, fall back to default case
2028 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2029 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
2030 break;
2031 }
2032 // FALL THROUGH
2033
2034 default: // FORCE_NONE
2035 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2036 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2037 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2038 device = AUDIO_DEVICE_IN_USB_DEVICE;
2039 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2040 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2041 }
2042 break;
2043
2044 case AUDIO_POLICY_FORCE_SPEAKER:
2045 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
2046 device = AUDIO_DEVICE_IN_BACK_MIC;
2047 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2048 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2049 }
2050 break;
2051 }
2052 break;
2053
2054 case AUDIO_SOURCE_VOICE_RECOGNITION:
2055 case AUDIO_SOURCE_HOTWORD:
2056 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
2057 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2058 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
2059 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2060 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2061 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2062 device = AUDIO_DEVICE_IN_USB_DEVICE;
2063 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) {
2064 device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
2065 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2066 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2067 }
2068 break;
2069 case AUDIO_SOURCE_CAMCORDER:
2070 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
2071 device = AUDIO_DEVICE_IN_BACK_MIC;
2072 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2073 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2074 }
2075 break;
2076 case AUDIO_SOURCE_VOICE_DOWNLINK:
2077 case AUDIO_SOURCE_VOICE_CALL:
2078 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
2079 device = AUDIO_DEVICE_IN_VOICE_CALL;
2080 }
2081 break;
2082 case AUDIO_SOURCE_REMOTE_SUBMIX:
2083 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
2084 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
2085 }
2086 break;
2087#ifdef AUDIO_EXTN_FM_ENABLED
2088 case AUDIO_SOURCE_FM_RX:
2089 device = AUDIO_DEVICE_IN_FM_RX;
2090 break;
2091 case AUDIO_SOURCE_FM_RX_A2DP:
2092 device = AUDIO_DEVICE_IN_FM_RX_A2DP;
2093 break;
2094#endif
2095 default:
2096 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
2097 break;
2098 }
2099 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
2100 return device;
2101}
2102
2103bool AudioPolicyManagerCustom::isVirtualInputDevice(audio_devices_t device)
2104{
2105 if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
2106 device &= ~AUDIO_DEVICE_BIT_IN;
2107 if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
2108 return true;
2109 }
2110 return false;
2111}
2112
2113bool AudioPolicyManagerCustom::deviceDistinguishesOnAddress(audio_devices_t device) {
2114 return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL) != 0);
2115}
2116
2117AudioPolicyManagerCustom::device_category AudioPolicyManagerCustom::getDeviceCategory(audio_devices_t device)
2118{
2119 switch(getDeviceForVolume(device)) {
2120 case AUDIO_DEVICE_OUT_EARPIECE:
2121 return DEVICE_CATEGORY_EARPIECE;
2122 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
2123 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
2124 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
2125 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
2126 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
2127 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
2128#ifdef AUDIO_EXTN_FM_ENABLED
2129 case AUDIO_DEVICE_OUT_FM:
2130#endif
2131 return DEVICE_CATEGORY_HEADSET;
2132 case AUDIO_DEVICE_OUT_LINE:
2133 case AUDIO_DEVICE_OUT_AUX_DIGITAL:
2134 /*USB? Remote submix?*/
2135 return DEVICE_CATEGORY_EXT_MEDIA;
2136 case AUDIO_DEVICE_OUT_SPEAKER:
2137 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
2138 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
2139 case AUDIO_DEVICE_OUT_USB_ACCESSORY:
2140 case AUDIO_DEVICE_OUT_USB_DEVICE:
2141 case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
2142#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
2143 case AUDIO_DEVICE_OUT_PROXY:
2144#endif
2145 default:
2146 return DEVICE_CATEGORY_SPEAKER;
2147 }
2148}
2149
2150float AudioPolicyManagerCustom::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
2151 int indexInUi)
2152{
2153 device_category deviceCategory = getDeviceCategory(device);
2154 const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
2155
2156 // the volume index in the UI is relative to the min and max volume indices for this stream type
2157 int nbSteps = 1 + curve[VOLMAX].mIndex -
2158 curve[VOLMIN].mIndex;
2159 int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
2160 (streamDesc.mIndexMax - streamDesc.mIndexMin);
2161
2162 // find what part of the curve this index volume belongs to, or if it's out of bounds
2163 int segment = 0;
2164 if (volIdx < curve[VOLMIN].mIndex) { // out of bounds
2165 return 0.0f;
2166 } else if (volIdx < curve[VOLKNEE1].mIndex) {
2167 segment = 0;
2168 } else if (volIdx < curve[VOLKNEE2].mIndex) {
2169 segment = 1;
2170 } else if (volIdx <= curve[VOLMAX].mIndex) {
2171 segment = 2;
2172 } else { // out of bounds
2173 return 1.0f;
2174 }
2175
2176 // linear interpolation in the attenuation table in dB
2177 float decibels = curve[segment].mDBAttenuation +
2178 ((float)(volIdx - curve[segment].mIndex)) *
2179 ( (curve[segment+1].mDBAttenuation -
2180 curve[segment].mDBAttenuation) /
2181 ((float)(curve[segment+1].mIndex -
2182 curve[segment].mIndex)) );
2183
2184 float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
2185
2186 ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
2187 curve[segment].mIndex, volIdx,
2188 curve[segment+1].mIndex,
2189 curve[segment].mDBAttenuation,
2190 decibels,
2191 curve[segment+1].mDBAttenuation,
2192 amplification);
2193
2194 return amplification;
2195}
2196
2197float AudioPolicyManagerCustom::computeVolume(audio_stream_type_t stream,
2198 int index,
2199 audio_io_handle_t output,
2200 audio_devices_t device)
2201{
2202 float volume = 1.0;
2203 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2204 StreamDescriptor &streamDesc = mStreams[stream];
2205
2206 if (device == AUDIO_DEVICE_NONE) {
2207 device = outputDesc->device();
2208 }
2209
2210 // if volume is not 0 (not muted), force media volume to max on digital output
2211 if (stream == AUDIO_STREAM_MUSIC &&
2212 index != mStreams[stream].mIndexMin &&
2213 (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
2214#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
2215 device == AUDIO_DEVICE_OUT_PROXY ||
2216#endif
2217 device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
2218 return 1.0;
2219 }
2220
2221#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
2222 if (stream == AUDIO_STREAM_INCALL_MUSIC) {
2223 return 1.0;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002224 }
2225#endif
Naresh Tanniru36c08932014-01-27 18:40:53 +05302226
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002227 volume = volIndexToAmpl(device, streamDesc, index);
2228
2229 // if a headset is connected, apply the following rules to ring tones and notifications
2230 // to avoid sound level bursts in user's ears:
2231 // - always attenuate ring tones and notifications volume by 6dB
2232 // - if music is playing, always limit the volume to current music volume,
2233 // with a minimum threshold at -36dB so that notification is always perceived.
2234 const routing_strategy stream_strategy = getStrategy(stream);
2235 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
2236 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
2237 AUDIO_DEVICE_OUT_WIRED_HEADSET |
2238 AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
2239 ((stream_strategy == STRATEGY_SONIFICATION)
2240 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
2241 || (stream == AUDIO_STREAM_SYSTEM)
2242 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
2243 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
2244 streamDesc.mCanBeMuted) {
2245 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
2246 // when the phone is ringing we must consider that music could have been paused just before
2247 // by the music application and behave as if music was active if the last music track was
2248 // just stopped
2249 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
2250 mLimitRingtoneVolume) {
2251 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
2252 float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
2253 mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
2254 output,
2255 musicDevice);
2256 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
2257 musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
2258 if (volume > minVol) {
2259 volume = minVol;
2260 ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
Naresh Tanniru36c08932014-01-27 18:40:53 +05302261 }
Naresh Tanniru36c08932014-01-27 18:40:53 +05302262 }
2263 }
2264
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002265 return volume;
Naresh Tanniru36c08932014-01-27 18:40:53 +05302266}
2267
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002268status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
2269 int index,
2270 audio_io_handle_t output,
2271 audio_devices_t device,
2272 int delayMs,
2273 bool force)
Karthik Reddy Katta060a6c42014-05-20 15:21:28 +05302274{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002275
2276 // do not change actual stream volume if the stream is muted
2277 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
2278 ALOGVV("checkAndSetVolume() stream %d muted count %d",
2279 stream, mOutputs.valueFor(output)->mMuteCount[stream]);
2280 return NO_ERROR;
2281 }
2282
2283 // do not change in call volume if bluetooth is connected and vice versa
2284 if ((stream == AUDIO_STREAM_VOICE_CALL &&
2285 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
2286 (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
2287 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
2288 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
2289 stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
2290 return INVALID_OPERATION;
2291 }
2292
2293 float volume = computeVolume(stream, index, output, device);
2294 // We actually change the volume if:
2295 // - the float value returned by computeVolume() changed
2296 // - the force flag is set
2297 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
2298 force) {
2299 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
2300 ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
2301 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
2302 // enabled
2303 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
2304 mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
2305#ifdef AUDIO_EXTN_FM_ENABLED
2306 } else if (stream == AUDIO_STREAM_MUSIC &&
2307 output == mPrimaryOutput) {
2308 if (volume >= 0) {
2309 AudioParameter param = AudioParameter();
2310 param.addFloat(String8("fm_volume"), volume);
2311 ALOGV("checkAndSetVolume setParameters volume, volume=:%f delay=:%d",volume,delayMs*2);
2312 //Double delayMs to avoid sound burst while device switch.
2313 mpClientInterface->setParameters(mPrimaryOutput, param.toString(), delayMs*2);
2314 }
2315#endif
2316 }
2317 mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
2318 }
2319
2320 if (stream == AUDIO_STREAM_VOICE_CALL ||
2321 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
2322 float voiceVolume;
2323 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
2324 if (stream == AUDIO_STREAM_VOICE_CALL) {
2325 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
2326 } else {
2327 voiceVolume = 1.0;
2328 }
2329
2330 if (voiceVolume != mLastVoiceVolume && ((output == mPrimaryOutput) ||
2331 isDirectOutput(output))) {
2332 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
2333 mLastVoiceVolume = voiceVolume;
2334 }
2335 }
2336
2337 return NO_ERROR;
Karthik Reddy Katta060a6c42014-05-20 15:21:28 +05302338}
2339
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002340bool AudioPolicyManagerCustom::isStateInCall(int state) {
2341 return ((state == AUDIO_MODE_IN_CALL) || (state == AUDIO_MODE_IN_COMMUNICATION) ||
2342 ((state == AUDIO_MODE_RINGTONE) && (mPrevPhoneState == AUDIO_MODE_IN_CALL)));
2343}
2344
2345
2346extern "C" AudioPolicyInterface* createAudioPolicyManager(
2347 AudioPolicyClientInterface *clientInterface)
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002348{
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002349 return new AudioPolicyManager(clientInterface);
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002350}
2351
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002352extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002353{
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002354 delete interface;
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002355}
2356
2357}; // namespace android