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