blob: ec48a718a38737ffc39d3f696f96c0fcbd50db57 [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
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001563 //check if it's multi-channel AAC (includes sub formats) and FLAC format
1564 if ((popcount(offloadInfo.channel_mask) > 2) &&
1565 (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
1566 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC))) {
1567 ALOGD("offload disabled for multi-channel AAC and FLAC format");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001568 return false;
1569 }
1570
1571 if (offloadInfo.has_video)
1572 {
1573 if(property_get("av.offload.enable", propValue, NULL)) {
1574 bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1575 if (!prop_enabled) {
1576 ALOGW("offload disabled by av.offload.enable = %s ", propValue );
1577 return false;
1578 }
1579 } else {
1580 return false;
1581 }
1582
1583 if(offloadInfo.is_streaming) {
1584 if (property_get("av.streaming.offload.enable", propValue, NULL)) {
1585 bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1586 if (!prop_enabled) {
1587 ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
1588 return false;
1589 }
1590 } else {
1591 //Do not offload AV streamnig if the property is not defined
1592 return false;
1593 }
1594 }
1595 ALOGD("copl: isOffloadSupported: has_video == true, property\
1596 set to enable offload");
1597 }
1598 }
1599
1600 //If duration is less than minimum value defined in property, return false
1601 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1602 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1603 ALOGD("copl: Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1604 return false;
1605 }
1606 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1607 ALOGD("copl: Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
1608 //duration checks only valid for MP3/AAC formats,
1609 //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001610 if ((offloadInfo.format == AUDIO_FORMAT_MP3) ||
1611 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
1612 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
1613 pcmOffload)
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001614 return false;
1615 }
1616
1617 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1618 // creating an offloaded track and tearing it down immediately after start when audioflinger
1619 // detects there is an active non offloadable effect.
1620 // FIXME: We should check the audio session here but we do not have it in this context.
1621 // This may prevent offloading in rare situations where effects are left active by apps
1622 // in the background.
1623 if (isNonOffloadableEffectEnabled()) {
1624 return false;
1625 }
1626
1627 // See if there is a profile to support this.
1628 // AUDIO_DEVICE_NONE
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001629 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001630 offloadInfo.sample_rate,
1631 offloadInfo.format,
1632 offloadInfo.channel_mask,
1633 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001634 ALOGD("copl: isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
1635 return (profile != 0);
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001636}
1637
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001638uint32_t AudioPolicyManagerCustom::nextUniqueId()
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001639{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001640 return android_atomic_inc(&mNextUniqueId);
1641}
1642
1643AudioPolicyManagerCustom::routing_strategy AudioPolicyManagerCustom::getStrategy(
1644 audio_stream_type_t stream) {
1645 // stream to strategy mapping
1646 switch (stream) {
1647 case AUDIO_STREAM_VOICE_CALL:
1648 case AUDIO_STREAM_BLUETOOTH_SCO:
1649 return STRATEGY_PHONE;
1650 case AUDIO_STREAM_RING:
1651 case AUDIO_STREAM_ALARM:
1652 return STRATEGY_SONIFICATION;
1653 case AUDIO_STREAM_NOTIFICATION:
1654 return STRATEGY_SONIFICATION_RESPECTFUL;
1655 case AUDIO_STREAM_DTMF:
1656 return STRATEGY_DTMF;
1657 default:
1658 ALOGE("unknown stream type");
1659 case AUDIO_STREAM_SYSTEM:
1660 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1661 // while key clicks are played produces a poor result
1662 case AUDIO_STREAM_TTS:
1663 case AUDIO_STREAM_MUSIC:
1664#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
1665 case AUDIO_STREAM_INCALL_MUSIC:
1666#endif
1667 return STRATEGY_MEDIA;
1668 case AUDIO_STREAM_ENFORCED_AUDIBLE:
1669 return STRATEGY_ENFORCED_AUDIBLE;
Naresh Tanniru36c08932014-01-27 18:40:53 +05301670 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001671}
Naresh Tanniru36c08932014-01-27 18:40:53 +05301672
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001673void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
1674 switch(stream) {
1675 case AUDIO_STREAM_MUSIC:
1676 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
1677 updateDevicesAndOutputs();
1678 break;
1679 default:
1680 break;
Naresh Tanniru36c08932014-01-27 18:40:53 +05301681 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001682}
Naresh Tanniru36c08932014-01-27 18:40:53 +05301683
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001684audio_devices_t AudioPolicyManagerCustom::getDeviceForStrategy(routing_strategy strategy,
1685 bool fromCache)
1686{
1687 uint32_t device = AUDIO_DEVICE_NONE;
1688
1689 if (fromCache) {
1690 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
1691 strategy, mDeviceForStrategy[strategy]);
1692 return mDeviceForStrategy[strategy];
Naresh Tanniru36c08932014-01-27 18:40:53 +05301693 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001694 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
1695 switch (strategy) {
Naresh Tanniru36c08932014-01-27 18:40:53 +05301696
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001697 case STRATEGY_SONIFICATION_RESPECTFUL:
1698 if (isInCall()) {
1699 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1700 } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
1701 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
1702 // while media is playing on a remote device, use the the sonification behavior.
1703 // Note that we test this usecase before testing if media is playing because
1704 // the isStreamActive() method only informs about the activity of a stream, not
1705 // if it's for local playback. Note also that we use the same delay between both tests
1706 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1707 //user "safe" speaker if available instead of normal speaker to avoid triggering
1708 //other acoustic safety mechanisms for notification
1709 if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
1710 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
1711 } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
1712 // while media is playing (or has recently played), use the same device
1713 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1714 } else {
1715 // when media is not playing anymore, fall back on the sonification behavior
1716 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
1717 //user "safe" speaker if available instead of normal speaker to avoid triggering
1718 //other acoustic safety mechanisms for notification
1719 if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
1720 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001721 }
1722
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001723 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001724
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001725 case STRATEGY_DTMF:
1726 if (!isInCall()) {
1727 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1728 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
1729 break;
1730 }
1731 // when in call, DTMF and PHONE strategies follow the same rules
1732 // FALL THROUGH
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001733
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001734 case STRATEGY_PHONE:
1735 // Force use of only devices on primary output if:
1736 // - in call AND
1737 // - cannot route from voice call RX OR
1738 // - audio HAL version is < 3.0 and TX device is on the primary HW module
1739 if (mPhoneState == AUDIO_MODE_IN_CALL) {
1740 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
1741 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
1742 if (((mAvailableInputDevices.types() &
1743 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
1744 (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) &&
1745 (hwOutputDesc->getAudioPort()->mModule->mHalVersion <
1746 AUDIO_DEVICE_API_VERSION_3_0))) {
1747 availableOutputDeviceTypes = availablePrimaryOutputDevices();
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001748 }
1749 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001750 // for phone strategy, we first consider the forced use and then the available devices by order
1751 // of priority
1752 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
1753 case AUDIO_POLICY_FORCE_BT_SCO:
1754 if (!isInCall() || strategy != STRATEGY_DTMF) {
1755 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1756 if (device) break;
1757 }
1758 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1759 if (device) break;
1760 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
1761 if (device) break;
1762 // if SCO device is requested but no SCO device is available, fall back to default case
1763 // FALL THROUGH
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001764
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001765 default: // FORCE_NONE
1766 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
1767 if (!isInCall() &&
1768 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1769 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1770 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1771 if (device) break;
1772 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1773 if (device) break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001774 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001775 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1776 if (device) break;
1777 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1778 if (device) break;
1779 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1780 if (device) break;
1781 if (mPhoneState != AUDIO_MODE_IN_CALL) {
1782 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1783 if (device) break;
1784 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1785 if (device) break;
1786 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1787 if (device) break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001788 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001789
1790 // Allow voice call on USB ANLG DOCK headset
1791 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1792 if (device) break;
1793
1794 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
1795 if (device) break;
1796 device = mDefaultOutputDevice->mDeviceType;
1797 if (device == AUDIO_DEVICE_NONE) {
1798 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
1799 }
1800 break;
1801
1802 case AUDIO_POLICY_FORCE_SPEAKER:
1803 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
1804 // A2DP speaker when forcing to speaker output
1805 if (!isInCall() &&
1806 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1807 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1808 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1809 if (device) break;
1810 }
1811 if (mPhoneState != AUDIO_MODE_IN_CALL) {
1812 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1813 if (device) break;
1814 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1815 if (device) break;
1816 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1817 if (device) break;
1818 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1819 if (device) break;
1820 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1821 if (device) break;
1822 }
1823 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
1824 if (device) break;
1825 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1826 if (device) break;
1827 device = mDefaultOutputDevice->mDeviceType;
1828 if (device == AUDIO_DEVICE_NONE) {
1829 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
1830 }
1831 break;
1832 }
1833
1834 if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
1835 // when in call, get the device for Phone strategy
1836 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1837 break;
1838 }
1839
1840#ifdef AUDIO_EXTN_FM_ENABLED
1841 if (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_FM) {
1842 if (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER) {
1843 device = AUDIO_DEVICE_OUT_SPEAKER;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001844 }
1845 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001846#endif
1847 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001848
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001849 case STRATEGY_SONIFICATION:
1850
1851 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1852 // handleIncallSonification().
1853 if (isInCall()) {
1854 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1855 break;
1856 }
1857 // FALL THROUGH
1858
1859 case STRATEGY_ENFORCED_AUDIBLE:
1860 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
1861 // except:
1862 // - when in call where it doesn't default to STRATEGY_PHONE behavior
1863 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
1864
1865 if ((strategy == STRATEGY_SONIFICATION) ||
1866 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
1867 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1868 if (device == AUDIO_DEVICE_NONE) {
1869 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001870 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001871 }
1872 // The second device used for sonification is the same as the device used by media strategy
1873 // FALL THROUGH
1874
1875 case STRATEGY_MEDIA: {
1876 uint32_t device2 = AUDIO_DEVICE_NONE;
1877
1878 if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
1879 // when in call, get the device for Phone strategy
1880 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
1881 break;
1882 }
1883#ifdef AUDIO_EXTN_FM_ENABLED
1884 if (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER) {
1885 device = AUDIO_DEVICE_OUT_SPEAKER;
1886 break;
1887 }
1888#endif
1889
1890 if (strategy != STRATEGY_SONIFICATION) {
1891 // no sonification on remote submix (e.g. WFD)
1892 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1893 }
1894 if ((device2 == AUDIO_DEVICE_NONE) &&
1895 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
1896 (getA2dpOutput() != 0) && !mA2dpSuspended) {
1897 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
1898 if (device2 == AUDIO_DEVICE_NONE) {
1899 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07001900 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001901 if (device2 == AUDIO_DEVICE_NONE) {
1902 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1903 }
1904 }
1905 if (device2 == AUDIO_DEVICE_NONE) {
1906 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1907 }
1908 if ((device2 == AUDIO_DEVICE_NONE)) {
1909 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
1910 }
1911 if (device2 == AUDIO_DEVICE_NONE) {
1912 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
1913 }
1914 if (device2 == AUDIO_DEVICE_NONE) {
1915 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
1916 }
1917 if (device2 == AUDIO_DEVICE_NONE) {
1918 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
1919 }
1920 if (device2 == AUDIO_DEVICE_NONE) {
1921 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
1922 }
1923 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1924 && (device2 == AUDIO_DEVICE_NONE)) {
1925 // no sonification on aux digital (e.g. HDMI)
1926 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
1927 }
1928 if ((device2 == AUDIO_DEVICE_NONE) &&
1929 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)
1930 && (strategy != STRATEGY_SONIFICATION)) {
1931 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
1932 }
1933#ifdef AUDIO_EXTN_FM_ENABLED
1934 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1935 && (device2 == AUDIO_DEVICE_NONE)) {
1936 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_FM_TX;
1937 }
1938#endif
1939#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
1940 if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
1941 && (device2 == AUDIO_DEVICE_NONE)) {
1942 // no sonification on WFD sink
1943 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY;
1944 }
1945#endif
1946 if (device2 == AUDIO_DEVICE_NONE) {
1947 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
1948 }
1949 int device3 = AUDIO_DEVICE_NONE;
1950 if (strategy == STRATEGY_MEDIA) {
1951 // ARC, SPDIF and AUX_LINE can co-exist with others.
1952 device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC;
1953 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF);
1954 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE);
1955 }
1956
1957 device2 |= device3;
1958 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
1959 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
1960 device |= device2;
1961
1962 // If hdmi system audio mode is on, remove speaker out of output list.
1963 if ((strategy == STRATEGY_MEDIA) &&
1964 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
1965 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
1966 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
1967 }
1968
1969 if (device) break;
1970 device = mDefaultOutputDevice->mDeviceType;
1971 if (device == AUDIO_DEVICE_NONE) {
1972 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
1973 }
1974 } break;
1975
1976 default:
1977 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1978 break;
1979 }
1980
1981 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1982 return device;
1983}
1984
1985audio_devices_t AudioPolicyManagerCustom::getDeviceForInputSource(audio_source_t inputSource)
1986{
1987 uint32_t device = AUDIO_DEVICE_NONE;
1988 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
1989 ~AUDIO_DEVICE_BIT_IN;
1990 switch (inputSource) {
1991 case AUDIO_SOURCE_VOICE_UPLINK:
1992 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
1993 device = AUDIO_DEVICE_IN_VOICE_CALL;
1994 break;
1995 }
1996 break;
1997
1998 case AUDIO_SOURCE_DEFAULT:
1999 case AUDIO_SOURCE_MIC:
2000 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
2001 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
2002 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2003 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2004 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2005 device = AUDIO_DEVICE_IN_USB_DEVICE;
2006 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2007 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2008 }
2009 break;
2010
2011 case AUDIO_SOURCE_VOICE_COMMUNICATION:
2012 // Allow only use of devices on primary input if in call and HAL does not support routing
2013 // to voice call path.
2014 if ((mPhoneState == AUDIO_MODE_IN_CALL) &&
2015 (mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
2016 availableDeviceTypes = availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN;
2017 }
2018
2019 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
2020 case AUDIO_POLICY_FORCE_BT_SCO:
2021 // if SCO device is requested but no SCO device is available, fall back to default case
2022 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2023 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
2024 break;
2025 }
2026 // FALL THROUGH
2027
2028 default: // FORCE_NONE
2029 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2030 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2031 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2032 device = AUDIO_DEVICE_IN_USB_DEVICE;
2033 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2034 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2035 }
2036 break;
2037
2038 case AUDIO_POLICY_FORCE_SPEAKER:
2039 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
2040 device = AUDIO_DEVICE_IN_BACK_MIC;
2041 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2042 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2043 }
2044 break;
2045 }
2046 break;
2047
2048 case AUDIO_SOURCE_VOICE_RECOGNITION:
2049 case AUDIO_SOURCE_HOTWORD:
2050 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
2051 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
2052 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
2053 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
2054 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
2055 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
2056 device = AUDIO_DEVICE_IN_USB_DEVICE;
2057 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) {
2058 device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
2059 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2060 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2061 }
2062 break;
2063 case AUDIO_SOURCE_CAMCORDER:
2064 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
2065 device = AUDIO_DEVICE_IN_BACK_MIC;
2066 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
2067 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
2068 }
2069 break;
2070 case AUDIO_SOURCE_VOICE_DOWNLINK:
2071 case AUDIO_SOURCE_VOICE_CALL:
2072 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
2073 device = AUDIO_DEVICE_IN_VOICE_CALL;
2074 }
2075 break;
2076 case AUDIO_SOURCE_REMOTE_SUBMIX:
2077 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
2078 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
2079 }
2080 break;
2081#ifdef AUDIO_EXTN_FM_ENABLED
2082 case AUDIO_SOURCE_FM_RX:
2083 device = AUDIO_DEVICE_IN_FM_RX;
2084 break;
2085 case AUDIO_SOURCE_FM_RX_A2DP:
2086 device = AUDIO_DEVICE_IN_FM_RX_A2DP;
2087 break;
2088#endif
2089 default:
2090 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
2091 break;
2092 }
2093 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
2094 return device;
2095}
2096
2097bool AudioPolicyManagerCustom::isVirtualInputDevice(audio_devices_t device)
2098{
2099 if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
2100 device &= ~AUDIO_DEVICE_BIT_IN;
2101 if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
2102 return true;
2103 }
2104 return false;
2105}
2106
2107bool AudioPolicyManagerCustom::deviceDistinguishesOnAddress(audio_devices_t device) {
2108 return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL) != 0);
2109}
2110
2111AudioPolicyManagerCustom::device_category AudioPolicyManagerCustom::getDeviceCategory(audio_devices_t device)
2112{
2113 switch(getDeviceForVolume(device)) {
2114 case AUDIO_DEVICE_OUT_EARPIECE:
2115 return DEVICE_CATEGORY_EARPIECE;
2116 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
2117 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
2118 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
2119 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
2120 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
2121 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
2122#ifdef AUDIO_EXTN_FM_ENABLED
2123 case AUDIO_DEVICE_OUT_FM:
2124#endif
2125 return DEVICE_CATEGORY_HEADSET;
2126 case AUDIO_DEVICE_OUT_LINE:
2127 case AUDIO_DEVICE_OUT_AUX_DIGITAL:
2128 /*USB? Remote submix?*/
2129 return DEVICE_CATEGORY_EXT_MEDIA;
2130 case AUDIO_DEVICE_OUT_SPEAKER:
2131 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
2132 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
2133 case AUDIO_DEVICE_OUT_USB_ACCESSORY:
2134 case AUDIO_DEVICE_OUT_USB_DEVICE:
2135 case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
2136#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
2137 case AUDIO_DEVICE_OUT_PROXY:
2138#endif
2139 default:
2140 return DEVICE_CATEGORY_SPEAKER;
2141 }
2142}
2143
2144float AudioPolicyManagerCustom::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
2145 int indexInUi)
2146{
2147 device_category deviceCategory = getDeviceCategory(device);
2148 const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
2149
2150 // the volume index in the UI is relative to the min and max volume indices for this stream type
2151 int nbSteps = 1 + curve[VOLMAX].mIndex -
2152 curve[VOLMIN].mIndex;
2153 int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
2154 (streamDesc.mIndexMax - streamDesc.mIndexMin);
2155
2156 // find what part of the curve this index volume belongs to, or if it's out of bounds
2157 int segment = 0;
2158 if (volIdx < curve[VOLMIN].mIndex) { // out of bounds
2159 return 0.0f;
2160 } else if (volIdx < curve[VOLKNEE1].mIndex) {
2161 segment = 0;
2162 } else if (volIdx < curve[VOLKNEE2].mIndex) {
2163 segment = 1;
2164 } else if (volIdx <= curve[VOLMAX].mIndex) {
2165 segment = 2;
2166 } else { // out of bounds
2167 return 1.0f;
2168 }
2169
2170 // linear interpolation in the attenuation table in dB
2171 float decibels = curve[segment].mDBAttenuation +
2172 ((float)(volIdx - curve[segment].mIndex)) *
2173 ( (curve[segment+1].mDBAttenuation -
2174 curve[segment].mDBAttenuation) /
2175 ((float)(curve[segment+1].mIndex -
2176 curve[segment].mIndex)) );
2177
2178 float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
2179
2180 ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
2181 curve[segment].mIndex, volIdx,
2182 curve[segment+1].mIndex,
2183 curve[segment].mDBAttenuation,
2184 decibels,
2185 curve[segment+1].mDBAttenuation,
2186 amplification);
2187
2188 return amplification;
2189}
2190
2191float AudioPolicyManagerCustom::computeVolume(audio_stream_type_t stream,
2192 int index,
2193 audio_io_handle_t output,
2194 audio_devices_t device)
2195{
2196 float volume = 1.0;
2197 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2198 StreamDescriptor &streamDesc = mStreams[stream];
2199
2200 if (device == AUDIO_DEVICE_NONE) {
2201 device = outputDesc->device();
2202 }
2203
2204 // if volume is not 0 (not muted), force media volume to max on digital output
2205 if (stream == AUDIO_STREAM_MUSIC &&
2206 index != mStreams[stream].mIndexMin &&
2207 (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
2208#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
2209 device == AUDIO_DEVICE_OUT_PROXY ||
2210#endif
2211 device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET)) {
2212 return 1.0;
2213 }
2214
2215#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
2216 if (stream == AUDIO_STREAM_INCALL_MUSIC) {
2217 return 1.0;
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002218 }
2219#endif
Naresh Tanniru36c08932014-01-27 18:40:53 +05302220
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002221 volume = volIndexToAmpl(device, streamDesc, index);
2222
2223 // if a headset is connected, apply the following rules to ring tones and notifications
2224 // to avoid sound level bursts in user's ears:
2225 // - always attenuate ring tones and notifications volume by 6dB
2226 // - if music is playing, always limit the volume to current music volume,
2227 // with a minimum threshold at -36dB so that notification is always perceived.
2228 const routing_strategy stream_strategy = getStrategy(stream);
2229 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
2230 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
2231 AUDIO_DEVICE_OUT_WIRED_HEADSET |
2232 AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
2233 ((stream_strategy == STRATEGY_SONIFICATION)
2234 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
2235 || (stream == AUDIO_STREAM_SYSTEM)
2236 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
2237 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
2238 streamDesc.mCanBeMuted) {
2239 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
2240 // when the phone is ringing we must consider that music could have been paused just before
2241 // by the music application and behave as if music was active if the last music track was
2242 // just stopped
2243 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
2244 mLimitRingtoneVolume) {
2245 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
2246 float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
2247 mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
2248 output,
2249 musicDevice);
2250 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
2251 musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
2252 if (volume > minVol) {
2253 volume = minVol;
2254 ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
Naresh Tanniru36c08932014-01-27 18:40:53 +05302255 }
Naresh Tanniru36c08932014-01-27 18:40:53 +05302256 }
2257 }
2258
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002259 return volume;
Naresh Tanniru36c08932014-01-27 18:40:53 +05302260}
2261
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002262status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
2263 int index,
2264 audio_io_handle_t output,
2265 audio_devices_t device,
2266 int delayMs,
2267 bool force)
Karthik Reddy Katta060a6c42014-05-20 15:21:28 +05302268{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002269
2270 // do not change actual stream volume if the stream is muted
2271 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
2272 ALOGVV("checkAndSetVolume() stream %d muted count %d",
2273 stream, mOutputs.valueFor(output)->mMuteCount[stream]);
2274 return NO_ERROR;
2275 }
2276
2277 // do not change in call volume if bluetooth is connected and vice versa
2278 if ((stream == AUDIO_STREAM_VOICE_CALL &&
2279 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
2280 (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
2281 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
2282 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
2283 stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
2284 return INVALID_OPERATION;
2285 }
2286
2287 float volume = computeVolume(stream, index, output, device);
2288 // We actually change the volume if:
2289 // - the float value returned by computeVolume() changed
2290 // - the force flag is set
2291 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
2292 force) {
2293 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
2294 ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
2295 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
2296 // enabled
2297 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
2298 mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
2299#ifdef AUDIO_EXTN_FM_ENABLED
2300 } else if (stream == AUDIO_STREAM_MUSIC &&
2301 output == mPrimaryOutput) {
2302 if (volume >= 0) {
2303 AudioParameter param = AudioParameter();
2304 param.addFloat(String8("fm_volume"), volume);
2305 ALOGV("checkAndSetVolume setParameters volume, volume=:%f delay=:%d",volume,delayMs*2);
2306 //Double delayMs to avoid sound burst while device switch.
2307 mpClientInterface->setParameters(mPrimaryOutput, param.toString(), delayMs*2);
2308 }
2309#endif
2310 }
2311 mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
2312 }
2313
2314 if (stream == AUDIO_STREAM_VOICE_CALL ||
2315 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
2316 float voiceVolume;
2317 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
2318 if (stream == AUDIO_STREAM_VOICE_CALL) {
2319 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
2320 } else {
2321 voiceVolume = 1.0;
2322 }
2323
2324 if (voiceVolume != mLastVoiceVolume && ((output == mPrimaryOutput) ||
2325 isDirectOutput(output))) {
2326 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
2327 mLastVoiceVolume = voiceVolume;
2328 }
2329 }
2330
2331 return NO_ERROR;
Karthik Reddy Katta060a6c42014-05-20 15:21:28 +05302332}
2333
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07002334bool AudioPolicyManagerCustom::isStateInCall(int state) {
2335 return ((state == AUDIO_MODE_IN_CALL) || (state == AUDIO_MODE_IN_COMMUNICATION) ||
2336 ((state == AUDIO_MODE_RINGTONE) && (mPrevPhoneState == AUDIO_MODE_IN_CALL)));
2337}
2338
2339
2340extern "C" AudioPolicyInterface* createAudioPolicyManager(
2341 AudioPolicyClientInterface *clientInterface)
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002342{
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002343 return new AudioPolicyManager(clientInterface);
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002344}
2345
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002346extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002347{
Mingming Yin0ae14ea2014-07-09 17:55:56 -07002348 delete interface;
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07002349}
2350
2351}; // namespace android