blob: 03dec5752fd51c3d769343120036baa07682f74a [file] [log] [blame]
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -07001/*
Sharad Sanglef2e11662015-05-28 16:15:16 +05302 * Copyright (c) 2013-2015, 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
Sharad Sanglef2e11662015-05-28 16:15:16 +053020#define LOG_TAG "AudioPolicyManagerCustom"
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070021//#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
Sharad Sanglef2e11662015-05-28 16:15:16 +053030#define MIN(a, b) ((a) < (b) ? (a) : (b))
31
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070032// A device mask for all audio output devices that are considered "remote" when evaluating
33// active output devices in isStreamActiveRemotely()
34#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070035// A device mask for all audio input and output devices where matching inputs/outputs on device
36// type alone is not enough: the address must match too
37#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
38 AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
Sharad Sanglef2e11662015-05-28 16:15:16 +053039// Following delay should be used if the calculated routing delay from all active
40// input streams is higher than this value
41#define MAX_VOICE_CALL_START_DELAY_MS 100
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070042
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070043#include <inttypes.h>
Mingming Yin0ae14ea2014-07-09 17:55:56 -070044#include <math.h>
Mingming Yin0670f162014-06-12 16:05:49 -070045
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070046#include <cutils/properties.h>
47#include <utils/Log.h>
48#include <hardware/audio.h>
49#include <hardware/audio_effect.h>
50#include <media/AudioParameter.h>
51#include <soundtrigger/SoundTrigger.h>
52#include "AudioPolicyManager.h"
Sharad Sanglef2e11662015-05-28 16:15:16 +053053#include <policy.h>
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070054
55namespace android {
Ravi Kumar Alamanda89a81422013-10-08 23:47:55 -070056
57// ----------------------------------------------------------------------------
58// AudioPolicyInterface implementation
59// ----------------------------------------------------------------------------
Sharad Sanglef2e11662015-05-28 16:15:16 +053060extern "C" AudioPolicyInterface* createAudioPolicyManager(
61 AudioPolicyClientInterface *clientInterface)
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070062{
Sharad Sanglef2e11662015-05-28 16:15:16 +053063 return new AudioPolicyManagerCustom(clientInterface);
64}
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070065
Sharad Sanglef2e11662015-05-28 16:15:16 +053066extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
67{
68 delete interface;
69}
70
71status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t device,
72 audio_policy_dev_state_t state,
73 const char *device_address,
74 const char *device_name)
75{
76 ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
77 device, state, device_address, device_name);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070078
79 // connect/disconnect only 1 device at a time
80 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
81
Sharad Sanglef2e11662015-05-28 16:15:16 +053082 sp<DeviceDescriptor> devDesc =
83 mHwModules.getDeviceDescriptor(device, device_address, device_name);
84
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070085 // handle output devices
86 if (audio_is_output_device(device)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070087 SortedVector <audio_io_handle_t> outputs;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070088
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070089 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -070090
91 // save a copy of the opened output descriptors before any output is opened or closed
92 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
93 mPreviousOutputs = mOutputs;
94 switch (state)
95 {
96 // handle output device connection
Sharad Sanglef2e11662015-05-28 16:15:16 +053097 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -070098 if (index >= 0) {
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 Alamanda1cf2a592014-10-29 20:31:15 -0700106 if (index >= 0) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530107 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700108 if (module == 0) {
109 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
110 device);
111 mAvailableOutputDevices.remove(devDesc);
112 return INVALID_OPERATION;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700113 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530114 mAvailableOutputDevices[index]->attach(module);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700115 } else {
116 return NO_MEMORY;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700117 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700118
Sharad Sanglef2e11662015-05-28 16:15:16 +0530119 if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700120 mAvailableOutputDevices.remove(devDesc);
121 return INVALID_OPERATION;
122 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530123 // Propagate device availability to Engine
124 mEngine->setDeviceConnectionState(devDesc, state);
125
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700126 // outputs should never be empty here
127 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
128 "checkOutputsForDevice() returned no outputs but status OK");
129 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
130 outputs.size());
Sharad Sanglef2e11662015-05-28 16:15:16 +0530131
132 // Send connect to HALs
133 AudioParameter param = AudioParameter(devDesc->mAddress);
134 param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
135 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
136
137 } break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700138 // handle output device disconnection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700139 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
140 if (index < 0) {
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700141 ALOGW("setDeviceConnectionState() device not connected: %x", device);
142 return INVALID_OPERATION;
143 }
144
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700145 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
146
Sharad Sanglef2e11662015-05-28 16:15:16 +0530147 // Send Disconnect to HALs
148 AudioParameter param = AudioParameter(devDesc->mAddress);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700149 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
150 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
151
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700152 // remove device from available output devices
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700153 mAvailableOutputDevices.remove(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700154
Sharad Sanglef2e11662015-05-28 16:15:16 +0530155 checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
156
157 // Propagate device availability to Engine
158 mEngine->setDeviceConnectionState(devDesc, state);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700159 } break;
160
161 default:
162 ALOGE("setDeviceConnectionState() invalid state: %x", state);
163 return BAD_VALUE;
164 }
165
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700166 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
167 // output is suspended before any tracks are moved to it
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700168 checkA2dpSuspend();
169 checkOutputForAllStrategies();
170 // outputs must be closed after checkOutputForAllStrategies() is executed
171 if (!outputs.isEmpty()) {
172 for (size_t i = 0; i < outputs.size(); i++) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530173 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700174 // close unused outputs after device disconnection or direct outputs that have been
175 // opened by checkOutputsForDevice() to query dynamic parameters
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700176 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700177 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
178 (desc->mDirectOpenCount == 0))) {
179 closeOutput(outputs[i]);
180 }
181 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700182 // check again after closing A2DP output to reset mA2dpSuspended if needed
183 checkA2dpSuspend();
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700184 }
185
186 updateDevicesAndOutputs();
Sharad Sanglef2e11662015-05-28 16:15:16 +0530187 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
188 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700189 updateCallRouting(newDevice);
190 }
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700191 for (size_t i = 0; i < mOutputs.size(); i++) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530192 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
193 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
194 audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700195 // do not force device change on duplicated output because if device is 0, it will
196 // also force a device 0 for the two outputs it is duplicated to which may override
197 // a valid device selection on those outputs.
Sharad Sanglef2e11662015-05-28 16:15:16 +0530198 bool force = !desc->isDuplicated()
199 && (!device_distinguishes_on_address(device)
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700200 // always force when disconnecting (a non-duplicated device)
201 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
Sharad Sanglef2e11662015-05-28 16:15:16 +0530202 setOutputDevice(desc, newDevice, force, 0);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700203 }
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700204 }
205
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700206 mpClientInterface->onAudioPortListUpdate();
207 return NO_ERROR;
208 } // end if is output device
209
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700210 // handle input devices
211 if (audio_is_input_device(device)) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700212 SortedVector <audio_io_handle_t> inputs;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700213
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700214 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700215 switch (state)
216 {
217 // handle input device connection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700218 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
219 if (index >= 0) {
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700220 ALOGW("setDeviceConnectionState() device already connected: %d", device);
221 return INVALID_OPERATION;
222 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530223 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700224 if (module == NULL) {
225 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
226 device);
227 return INVALID_OPERATION;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700228 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530229 if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700230 return INVALID_OPERATION;
231 }
232
233 index = mAvailableInputDevices.add(devDesc);
234 if (index >= 0) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530235 mAvailableInputDevices[index]->attach(module);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700236 } else {
237 return NO_MEMORY;
238 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530239
240 // Set connect to HALs
241 AudioParameter param = AudioParameter(devDesc->mAddress);
242 param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
243 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
244
245 // Propagate device availability to Engine
246 mEngine->setDeviceConnectionState(devDesc, state);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700247 } break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700248
249 // handle input device disconnection
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700250 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
251 if (index < 0) {
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700252 ALOGW("setDeviceConnectionState() device not connected: %d", device);
253 return INVALID_OPERATION;
254 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700255
256 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
257
258 // Set Disconnect to HALs
Sharad Sanglef2e11662015-05-28 16:15:16 +0530259 AudioParameter param = AudioParameter(devDesc->mAddress);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700260 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
261 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
262
Sharad Sanglef2e11662015-05-28 16:15:16 +0530263 checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700264 mAvailableInputDevices.remove(devDesc);
265
Sharad Sanglef2e11662015-05-28 16:15:16 +0530266 // Propagate device availability to Engine
267 mEngine->setDeviceConnectionState(devDesc, state);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700268 } break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700269
270 default:
271 ALOGE("setDeviceConnectionState() invalid state: %x", state);
272 return BAD_VALUE;
273 }
274
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700275 closeAllInputs();
276
Sharad Sanglef2e11662015-05-28 16:15:16 +0530277 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700278 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
279 updateCallRouting(newDevice);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700280 }
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700281
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700282 mpClientInterface->onAudioPortListUpdate();
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700283 return NO_ERROR;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700284 } // end if is input device
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700285
286 ALOGW("setDeviceConnectionState() invalid device: %x", device);
287 return BAD_VALUE;
288}
Sharad Sanglef2e11662015-05-28 16:15:16 +0530289// This function checks for the parameters which can be offloaded.
290// This can be enhanced depending on the capability of the DSP and policy
291// of the system.
292bool AudioPolicyManagerCustom::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700293{
Sharad Sanglef2e11662015-05-28 16:15:16 +0530294 ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
295 " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
296 offloadInfo.sample_rate, offloadInfo.channel_mask,
297 offloadInfo.format,
298 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
299 offloadInfo.has_video);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700300
Sharad Sanglef2e11662015-05-28 16:15:16 +0530301 // Check if offload has been disabled
302 char propValue[PROPERTY_VALUE_MAX];
303 if (property_get("audio.offload.disable", propValue, "0")) {
304 if (atoi(propValue) != 0) {
305 ALOGV("offload disabled by audio.offload.disable=%s", propValue );
306 return false;
307 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700308 }
309
Sharad Sanglef2e11662015-05-28 16:15:16 +0530310 // Check if stream type is music, then only allow offload as of now.
311 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
312 {
313 ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
314 return false;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700315 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530316 //check if it's multi-channel AAC (includes sub formats) and FLAC format
317 if ((popcount(offloadInfo.channel_mask) > 2) &&
318 (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
319 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC)||
320 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS))) {
321 ALOGD("offload disabled for multi-channel AAC,FLAC and VORBIS format");
322 return false;
323 }
324
325 //TODO: enable audio offloading with video when ready
326 const bool allowOffloadWithVideo =
327 property_get_bool("audio.offload.video", false /* default_value */);
328 if (offloadInfo.has_video && !allowOffloadWithVideo) {
329 ALOGV("isOffloadSupported: has_video == true, returning false");
330 return false;
331 }
332
333 //If duration is less than minimum value defined in property, return false
334 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
335 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
336 ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
337 return false;
338 }
339 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
340 ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
341 //duration checks only valid for MP3/AAC/ formats,
342 //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
343 if ((offloadInfo.format == AUDIO_FORMAT_MP3) ||
344 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
345 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
346 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS) ||
347 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) ||
348 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) ||
349 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_ALAC) ||
350 ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_APE))
351 return false;
352
353 }
354
355 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
356 // creating an offloaded track and tearing it down immediately after start when audioflinger
357 // detects there is an active non offloadable effect.
358 // FIXME: We should check the audio session here but we do not have it in this context.
359 // This may prevent offloading in rare situations where effects are left active by apps
360 // in the background.
361 if (mEffects.isNonOffloadableEffectEnabled()) {
362 return false;
363 }
364 // Check for soundcard status
365 String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0,
366 String8("SND_CARD_STATUS"));
367 AudioParameter result = AudioParameter(valueStr);
368 int isonline = 0;
369 if ((result.getInt(String8("SND_CARD_STATUS"), isonline) == NO_ERROR)
370 && !isonline) {
371 ALOGD("copl: soundcard is offline rejecting offload request");
372 return false;
373 }
374 // See if there is a profile to support this.
375 // AUDIO_DEVICE_NONE
376 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
377 offloadInfo.sample_rate,
378 offloadInfo.format,
379 offloadInfo.channel_mask,
380 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
381 ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
382 return (profile != 0);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700383}
Sharad Sanglef2e11662015-05-28 16:15:16 +0530384audio_devices_t AudioPolicyManagerCustom::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
385 bool fromCache)
386{
387 audio_devices_t device = AUDIO_DEVICE_NONE;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700388
Sharad Sanglef2e11662015-05-28 16:15:16 +0530389 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
390 if (index >= 0) {
391 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
392 if (patchDesc->mUid != mUidCached) {
393 ALOGV("getNewOutputDevice() device %08x forced by patch %d",
394 outputDesc->device(), outputDesc->mPatchHandle);
395 return outputDesc->device();
396 }
397 }
398
399 // check the following by order of priority to request a routing change if necessary:
400 // 1: the strategy enforced audible is active and enforced on the output:
401 // use device for strategy enforced audible
402 // 2: we are in call or the strategy phone is active on the output:
403 // use device for strategy phone
404 // 3: the strategy for enforced audible is active but not enforced on the output:
405 // use the device for strategy enforced audible
406 // 4: the strategy sonification is active on the output:
407 // use device for strategy sonification
408 // 5: the strategy "respectful" sonification is active on the output:
409 // use device for strategy "respectful" sonification
410 // 6: the strategy accessibility is active on the output:
411 // use device for strategy accessibility
412 // 7: the strategy media is active on the output:
413 // use device for strategy media
414 // 8: the strategy DTMF is active on the output:
415 // use device for strategy DTMF
416 // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
417 // use device for strategy t-t-s
418 if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
419 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
420 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
421 } else if (isInCall() ||
422 isStrategyActive(outputDesc, STRATEGY_PHONE)||
423 isStrategyActive(mPrimaryOutput, STRATEGY_PHONE)) {
424 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
425 } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
426 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
427 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)||
428 (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION)
429 && (!isStrategyActive(mPrimaryOutput,STRATEGY_MEDIA)))) {
430 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
431 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)||
432 (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION_RESPECTFUL)
433 && (!isStrategyActive(mPrimaryOutput, STRATEGY_MEDIA)))) {
434 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
435 } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
436 device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
437 } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
438 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
439 } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
440 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
441 } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
442 device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
443 } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
444 device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
445 }
446
447 ALOGV("getNewOutputDevice() selected device %x", device);
448 return device;
449}
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700450void AudioPolicyManagerCustom::setPhoneState(audio_mode_t state)
451{
Sharad Sanglef2e11662015-05-28 16:15:16 +0530452 ALOGV("setPhoneState() state %d", state);
453 // store previous phone state for management of sonification strategy below
454 int oldState = mEngine->getPhoneState();
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700455
Sharad Sanglef2e11662015-05-28 16:15:16 +0530456 if (mEngine->setPhoneState(state) != NO_ERROR) {
457 ALOGW("setPhoneState() invalid or same state %d", state);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700458 return;
459 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530460 /// Opens: can these line be executed after the switch of volume curves???
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700461 // if leaving call state, handle special case of active streams
462 // pertaining to sonification strategy see handleIncallSonification()
463 if (isInCall()) {
464 ALOGV("setPhoneState() in call state management: new state is %d", state);
Sharad Sanglef2e11662015-05-28 16:15:16 +0530465 for (size_t j = 0; j < mOutputs.size(); j++) {
466 audio_io_handle_t curOutput = mOutputs.keyAt(j);
467 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
468 if (stream == AUDIO_STREAM_PATCH) {
469 continue;
470 }
471
472 handleIncallSonification((audio_stream_type_t)stream, false, true, curOutput);
473 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700474 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530475
476 // force reevaluating accessibility routing when call starts
477 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700478 }
479
Sharad Sanglef2e11662015-05-28 16:15:16 +0530480 /**
481 * Switching to or from incall state or switching between telephony and VoIP lead to force
482 * routing command.
483 */
484 bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
485 || (is_state_in_call(state) && (state != oldState)));
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700486
487 // check for device and output changes triggered by new phone state
488 checkA2dpSuspend();
489 checkOutputForAllStrategies();
490 updateDevicesAndOutputs();
491
Sharad Sanglef2e11662015-05-28 16:15:16 +0530492 sp<SwAudioOutputDescriptor> hwOutputDesc = mPrimaryOutput;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700493
494 int delayMs = 0;
495 if (isStateInCall(state)) {
496 nsecs_t sysTime = systemTime();
497 for (size_t i = 0; i < mOutputs.size(); i++) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530498 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700499 // mute media and sonification strategies and delay device switch by the largest
500 // latency of any output where either strategy is active.
501 // This avoid sending the ring tone or music tail into the earpiece or headset.
Sharad Sanglef2e11662015-05-28 16:15:16 +0530502 if ((isStrategyActive(desc, STRATEGY_MEDIA,
503 SONIFICATION_HEADSET_MUSIC_DELAY,
504 sysTime) ||
505 isStrategyActive(desc, STRATEGY_SONIFICATION,
506 SONIFICATION_HEADSET_MUSIC_DELAY,
507 sysTime)) &&
508 (delayMs < (int)desc->latency()*2)) {
509 delayMs = desc->latency()*2;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700510 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530511 setStrategyMute(STRATEGY_MEDIA, true, desc);
512 setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700513 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
Sharad Sanglef2e11662015-05-28 16:15:16 +0530514 setStrategyMute(STRATEGY_SONIFICATION, true, desc);
515 setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700516 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
517 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530518 ALOGV("Setting the delay from %dms to %dms", delayMs,
519 MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS));
520 delayMs = MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700521 }
522
Sharad Sanglef2e11662015-05-28 16:15:16 +0530523 if (hasPrimaryOutput()) {
524 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
525 // the device returned is not necessarily reachable via this output
526 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
527 // force routing command to audio hardware when ending call
528 // even if no device change is needed
529 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
530 rxDevice = mPrimaryOutput->device();
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700531 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700532
Sharad Sanglef2e11662015-05-28 16:15:16 +0530533 if (state == AUDIO_MODE_IN_CALL) {
534 updateCallRouting(rxDevice, delayMs);
535 } else if (oldState == AUDIO_MODE_IN_CALL) {
536 if (mCallRxPatch != 0) {
537 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
538 mCallRxPatch.clear();
539 }
540 if (mCallTxPatch != 0) {
541 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
542 mCallTxPatch.clear();
543 }
544 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
545 } else {
546 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700547 }
548 }
549
550 // if entering in call state, handle special case of active streams
551 // pertaining to sonification strategy see handleIncallSonification()
552 if (isStateInCall(state)) {
553 ALOGV("setPhoneState() in call state management: new state is %d", state);
Sharad Sanglef2e11662015-05-28 16:15:16 +0530554 for (size_t j = 0; j < mOutputs.size(); j++) {
555 audio_io_handle_t curOutput = mOutputs.keyAt(j);
556 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
557 if (stream == AUDIO_STREAM_PATCH) {
558 continue;
559 }
560 handleIncallSonification((audio_stream_type_t)stream, true, true, curOutput);
561 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700562 }
563 }
564
565 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
566 if (state == AUDIO_MODE_RINGTONE &&
567 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
568 mLimitRingtoneVolume = true;
569 } else {
570 mLimitRingtoneVolume = false;
571 }
572}
Sharad Sanglef2e11662015-05-28 16:15:16 +0530573status_t AudioPolicyManagerCustom::stopSource(sp<SwAudioOutputDescriptor> outputDesc,
574 audio_stream_type_t stream,
575 bool forceDeviceUpdate)
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700576{
Sharad Sanglef2e11662015-05-28 16:15:16 +0530577 // always handle stream stop, check which stream type is stopping
578 handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700579
Sharad Sanglef2e11662015-05-28 16:15:16 +0530580 // handle special case for sonification while in call
581 if (isInCall()) {
582 if (outputDesc->isDuplicated()) {
583 handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
584 handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700585 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530586 handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
587 }
588
589 if (outputDesc->mRefCount[stream] > 0) {
590 // decrement usage count of this stream on the output
591 outputDesc->changeRefCount(stream, -1);
592
593 // store time at which the stream was stopped - see isStreamActive()
594 if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
595 outputDesc->mStopTime[stream] = systemTime();
596 audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
597 // delay the device switch by twice the latency because stopOutput() is executed when
598 // the track stop() command is received and at that time the audio track buffer can
599 // still contain data that needs to be drained. The latency only covers the audio HAL
600 // and kernel buffers. Also the latency does not always include additional delay in the
601 // audio path (audio DSP, CODEC ...)
602 setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
603
604 // force restoring the device selection on other active outputs if it differs from the
605 // one being selected for this output
606 for (size_t i = 0; i < mOutputs.size(); i++) {
607 audio_io_handle_t curOutput = mOutputs.keyAt(i);
608 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
609 if (desc != outputDesc &&
610 desc->isActive() &&
611 outputDesc->sharesHwModuleWith(desc) &&
612 (newDevice != desc->device())) {
613 setOutputDevice(desc,
614 getNewOutputDevice(desc, false /*fromCache*/),
615 true,
616 outputDesc->latency()*2);
617 }
618 }
619 // update the outputs if stopping one with a stream that can affect notification routing
620 handleNotificationRoutingForStream(stream);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700621 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530622 return NO_ERROR;
623 } else {
624 ALOGW("stopOutput() refcount is already 0");
625 return INVALID_OPERATION;
626 }
627}
628status_t AudioPolicyManagerCustom::startSource(sp<SwAudioOutputDescriptor> outputDesc,
629 audio_stream_type_t stream,
630 audio_devices_t device,
631 uint32_t *delayMs)
632{
633 // cannot start playback of STREAM_TTS if any other output is being used
634 uint32_t beaconMuteLatency = 0;
635
636 *delayMs = 0;
637 if (stream == AUDIO_STREAM_TTS) {
638 ALOGV("\t found BEACON stream");
639 if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
640 return INVALID_OPERATION;
641 } else {
642 beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700643 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530644 } else {
645 // some playback other than beacon starts
646 beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
647 }
648
649 // increment usage count for this stream on the requested output:
650 // NOTE that the usage count is the same for duplicated output and hardware output which is
651 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
652 outputDesc->changeRefCount(stream, 1);
653
654 if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
655 // starting an output being rerouted?
656 if (device == AUDIO_DEVICE_NONE) {
657 device = getNewOutputDevice(outputDesc, false /*fromCache*/);
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700658 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530659 routing_strategy strategy = getStrategy(stream);
660 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
661 (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
662 (beaconMuteLatency > 0);
663 uint32_t waitMs = beaconMuteLatency;
664 bool force = false;
665 for (size_t i = 0; i < mOutputs.size(); i++) {
666 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
667 if (desc != outputDesc) {
668 // force a device change if any other output is managed by the same hw
669 // module and has a current device selection that differs from selected device.
670 // In this case, the audio HAL must receive the new device selection so that it can
671 // change the device currently selected by the other active output.
672 if (outputDesc->sharesHwModuleWith(desc) &&
673 desc->device() != device) {
674 force = true;
675 }
676 // wait for audio on other active outputs to be presented when starting
677 // a notification so that audio focus effect can propagate, or that a mute/unmute
678 // event occurred for beacon
679 uint32_t latency = desc->latency();
680 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
681 waitMs = latency;
682 }
683 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700684 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530685 uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force);
686
687 // handle special case for sonification while in call
688 if (isInCall()) {
689 handleIncallSonification(stream, true, false, outputDesc->mIoHandle);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700690 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530691
692 // apply volume rules for current stream and device if necessary
693 checkAndSetVolume(stream,
694 mStreams.valueFor(stream).getVolumeIndex(device),
695 outputDesc,
696 device);
697
698 // update the outputs if starting an output with a stream that can affect notification
699 // routing
700 handleNotificationRoutingForStream(stream);
701
702 // force reevaluating accessibility routing when ringtone or alarm starts
703 if (strategy == STRATEGY_SONIFICATION) {
704 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
705 }
706 }
707 else {
708 // handle special case for sonification while in call
709 if (isInCall()) {
710 handleIncallSonification(stream, true, false, outputDesc->mIoHandle);
711 }
712 }
713 return NO_ERROR;
714}
715void AudioPolicyManagerCustom::handleIncallSonification(audio_stream_type_t stream,
716 bool starting, bool stateChange,
717 audio_io_handle_t output)
718{
719 if(!hasPrimaryOutput()) {
720 return;
721 }
722 // no action needed for AUDIO_STREAM_PATCH stream type, it's for internal flinger tracks
723 if (stream == AUDIO_STREAM_PATCH) {
724 return;
725 }
726 // if the stream pertains to sonification strategy and we are in call we must
727 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
728 // in the device used for phone strategy and play the tone if the selected device does not
729 // interfere with the device used for phone strategy
730 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
731 // many times as there are active tracks on the output
732 const routing_strategy stream_strategy = getStrategy(stream);
733 if ((stream_strategy == STRATEGY_SONIFICATION) ||
734 ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
735 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
736 ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
737 stream, starting, outputDesc->mDevice, stateChange);
738 if (outputDesc->mRefCount[stream]) {
739 int muteCount = 1;
740 if (stateChange) {
741 muteCount = outputDesc->mRefCount[stream];
742 }
743 if (audio_is_low_visibility(stream)) {
744 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
745 for (int i = 0; i < muteCount; i++) {
746 setStreamMute(stream, starting, outputDesc);
747 }
748 } else {
749 ALOGV("handleIncallSonification() high visibility");
750 if (outputDesc->device() &
751 getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
752 ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
753 for (int i = 0; i < muteCount; i++) {
754 setStreamMute(stream, starting, outputDesc);
755 }
756 }
757 if (starting) {
758 mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
759 AUDIO_STREAM_VOICE_CALL);
760 } else {
761 mpClientInterface->stopTone();
762 }
763 }
764 }
765 }
766}
767void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
768 switch(stream) {
769 case AUDIO_STREAM_MUSIC:
770 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
771 updateDevicesAndOutputs();
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700772 break;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700773 default:
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700774 break;
Ravi Kumar Alamanda88d28cb2013-10-15 16:59:57 -0700775 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700776}
Sharad Sanglef2e11662015-05-28 16:15:16 +0530777status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
778 int index,
779 const sp<SwAudioOutputDescriptor>& outputDesc,
780 audio_devices_t device,
781 int delayMs, bool force)
782{
783 // do not change actual stream volume if the stream is muted
784 if (outputDesc->mMuteCount[stream] != 0) {
785 ALOGVV("checkAndSetVolume() stream %d muted count %d",
786 stream, outputDesc->mMuteCount[stream]);
787 return NO_ERROR;
788 }
789 audio_policy_forced_cfg_t forceUseForComm =
790 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
791 // do not change in call volume if bluetooth is connected and vice versa
792 if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
793 (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
794 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
795 stream, forceUseForComm);
796 return INVALID_OPERATION;
797 }
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700798
Sharad Sanglef2e11662015-05-28 16:15:16 +0530799 if (device == AUDIO_DEVICE_NONE) {
800 device = outputDesc->device();
801 }
802
803 float volumeDb = computeVolume(stream, index, device);
804 if (outputDesc->isFixedVolume(device)) {
805 volumeDb = 0.0f;
806 }
807
808 outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
809
810 if (stream == AUDIO_STREAM_VOICE_CALL ||
811 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
812 float voiceVolume;
813 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
814 if (stream == AUDIO_STREAM_VOICE_CALL) {
815 voiceVolume = (float)index/(float)mStreams.valueFor(stream).getVolumeIndexMax();
816 } else {
817 voiceVolume = 1.0;
818 }
819
820 if (voiceVolume != mLastVoiceVolume && ((outputDesc == mPrimaryOutput) ||
821 isDirectOutput(outputDesc->mIoHandle) || device & AUDIO_DEVICE_OUT_ALL_USB)) {
822 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
823 mLastVoiceVolume = voiceVolume;
824 }
825 }
826
827 return NO_ERROR;
828}
829bool AudioPolicyManagerCustom::isDirectOutput(audio_io_handle_t output) {
830 for (size_t i = 0; i < mOutputs.size(); i++) {
831 audio_io_handle_t curOutput = mOutputs.keyAt(i);
832 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
833 if ((curOutput == output) && (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
834 return true;
835 }
836 }
837 return false;
838}
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700839audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
840 audio_devices_t device,
Sharad Sanglef2e11662015-05-28 16:15:16 +0530841 audio_session_t session __unused,
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700842 audio_stream_type_t stream,
843 uint32_t samplingRate,
844 audio_format_t format,
845 audio_channel_mask_t channelMask,
846 audio_output_flags_t flags,
847 const audio_offload_info_t *offloadInfo)
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700848{
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700849 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
850 uint32_t latency = 0;
851 status_t status;
Mingming Yin0ae14ea2014-07-09 17:55:56 -0700852
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700853#ifdef AUDIO_POLICY_TEST
854 if (mCurOutput != 0) {
855 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
856 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
857
858 if (mTestOutputs[mCurOutput] == 0) {
859 ALOGV("getOutput() opening test output");
Sharad Sanglef2e11662015-05-28 16:15:16 +0530860 sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
861 mpClientInterface);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700862 outputDesc->mDevice = mTestDevice;
863 outputDesc->mLatency = mTestLatencyMs;
864 outputDesc->mFlags =
865 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
866 outputDesc->mRefCount[stream] = 0;
867 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
868 config.sample_rate = mTestSamplingRate;
869 config.channel_mask = mTestChannels;
870 config.format = mTestFormat;
871 if (offloadInfo != NULL) {
872 config.offload_info = *offloadInfo;
873 }
874 status = mpClientInterface->openOutput(0,
875 &mTestOutputs[mCurOutput],
876 &config,
877 &outputDesc->mDevice,
878 String8(""),
879 &outputDesc->mLatency,
880 outputDesc->mFlags);
881 if (status == NO_ERROR) {
882 outputDesc->mSamplingRate = config.sample_rate;
883 outputDesc->mFormat = config.format;
884 outputDesc->mChannelMask = config.channel_mask;
885 AudioParameter outputCmd = AudioParameter();
886 outputCmd.addInt(String8("set_id"),mCurOutput);
887 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
888 addOutput(mTestOutputs[mCurOutput], outputDesc);
889 }
890 }
891 return mTestOutputs[mCurOutput];
892 }
893#endif //AUDIO_POLICY_TEST
Sharad Sanglef2e11662015-05-28 16:15:16 +0530894 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
895 (stream != AUDIO_STREAM_MUSIC)) {
896 // compress should not be used for non-music streams
897 ALOGE("Offloading only allowed with music stream");
898 return 0;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700899 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530900 /*
901 * WFD audio routes back to target speaker when starting a ringtone playback.
902 * This is because primary output is reused for ringtone, so output device is
903 * updated based on SONIFICATION strategy for both ringtone and music playback.
904 * The same issue is not seen on remoted_submix HAL based WFD audio because
905 * primary output is not reused and a new output is created for ringtone playback.
906 * Issue is fixed by updating output flag to AUDIO_OUTPUT_FLAG_FAST when there is
907 * a non-music stream playback on WFD, so primary output is not reused for ringtone.
908 */
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700909 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
910 if ((availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY)
911 && (stream != AUDIO_STREAM_MUSIC)) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530912 ALOGD("WFD audio: use OUTPUT_FLAG_FAST for non music stream. flags:%x", flags );
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700913 //For voip paths
914 if(flags & AUDIO_OUTPUT_FLAG_DIRECT)
915 flags = AUDIO_OUTPUT_FLAG_DIRECT;
916 else //route every thing else to ULL path
917 flags = AUDIO_OUTPUT_FLAG_FAST;
918 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700919 // open a direct output if required by specified parameters
920 //force direct flag if offload flag is set: offloading implies a direct output stream
921 // and all common behaviors are driven by checking only the direct flag
922 // this should normally be set appropriately in the policy configuration file
923 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
924 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
925 }
926 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
927 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
928 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530929 // only allow deep buffering for music stream type
930 if (stream != AUDIO_STREAM_MUSIC) {
931 flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
932 }
933 if (stream == AUDIO_STREAM_TTS) {
934 flags = AUDIO_OUTPUT_FLAG_TTS;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700935 }
936
937 sp<IOProfile> profile;
938
939 // skip direct output selection if the request can obviously be attached to a mixed output
940 // and not explicitly requested
941 if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
942 audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
943 audio_channel_count_from_out_mask(channelMask) <= 2) {
944 goto non_direct_output;
945 }
946
947 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
948 // creating an offloaded track and tearing it down immediately after start when audioflinger
949 // detects there is an active non offloadable effect.
950 // FIXME: We should check the audio session here but we do not have it in this context.
951 // This may prevent offloading in rare situations where effects are left active by apps
952 // in the background.
953
Sharad Sanglef2e11662015-05-28 16:15:16 +0530954 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
955 !mEffects.isNonOffloadableEffectEnabled()) {
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700956 profile = getProfileForDirectOutput(device,
957 samplingRate,
958 format,
959 channelMask,
960 (audio_output_flags_t)flags);
961 }
962
963 if (profile != 0) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530964 sp<SwAudioOutputDescriptor> outputDesc = NULL;
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700965
966 for (size_t i = 0; i < mOutputs.size(); i++) {
Sharad Sanglef2e11662015-05-28 16:15:16 +0530967 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -0700968 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
969 outputDesc = desc;
970 // reuse direct output if currently open and configured with same parameters
971 if ((samplingRate == outputDesc->mSamplingRate) &&
972 (format == outputDesc->mFormat) &&
973 (channelMask == outputDesc->mChannelMask)) {
974 outputDesc->mDirectOpenCount++;
975 ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
976 return mOutputs.keyAt(i);
977 }
978 }
979 }
980 // close direct output if currently open and configured with different parameters
981 if (outputDesc != NULL) {
982 closeOutput(outputDesc->mIoHandle);
983 }
Sharad Sanglef2e11662015-05-28 16:15:16 +0530984
985 // if the selected profile is offloaded and no offload info was specified,
986 // create a default one
987 audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
988 if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
989 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
990 defaultOffloadInfo.sample_rate = samplingRate;
991 defaultOffloadInfo.channel_mask = channelMask;
992 defaultOffloadInfo.format = format;
993 defaultOffloadInfo.stream_type = stream;
994 defaultOffloadInfo.bit_rate = 0;
995 defaultOffloadInfo.duration_us = -1;
996 defaultOffloadInfo.has_video = true; // conservative
997 defaultOffloadInfo.is_streaming = true; // likely
998 offloadInfo = &defaultOffloadInfo;
999 }
1000
1001 outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001002 outputDesc->mDevice = device;
1003 outputDesc->mLatency = 0;
Sharad Sanglef2e11662015-05-28 16:15:16 +05301004 outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001005 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1006 config.sample_rate = samplingRate;
1007 config.channel_mask = channelMask;
1008 config.format = format;
1009 if (offloadInfo != NULL) {
1010 config.offload_info = *offloadInfo;
1011 }
Sharad Sanglef2e11662015-05-28 16:15:16 +05301012 status = mpClientInterface->openOutput(profile->getModuleHandle(),
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001013 &output,
1014 &config,
1015 &outputDesc->mDevice,
1016 String8(""),
1017 &outputDesc->mLatency,
1018 outputDesc->mFlags);
1019
1020 // only accept an output with the requested parameters
1021 if (status != NO_ERROR ||
1022 (samplingRate != 0 && samplingRate != config.sample_rate) ||
1023 (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
1024 (channelMask != 0 && channelMask != config.channel_mask)) {
1025 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
1026 "format %d %d, channelMask %04x %04x", output, samplingRate,
1027 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
1028 outputDesc->mChannelMask);
1029 if (output != AUDIO_IO_HANDLE_NONE) {
1030 mpClientInterface->closeOutput(output);
1031 }
Sharad Sanglef2e11662015-05-28 16:15:16 +05301032 // fall back to mixer output if possible when the direct output could not be open
1033 if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
1034 goto non_direct_output;
1035 }
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001036 return AUDIO_IO_HANDLE_NONE;
1037 }
1038 outputDesc->mSamplingRate = config.sample_rate;
1039 outputDesc->mChannelMask = config.channel_mask;
1040 outputDesc->mFormat = config.format;
1041 outputDesc->mRefCount[stream] = 0;
1042 outputDesc->mStopTime[stream] = 0;
1043 outputDesc->mDirectOpenCount = 1;
1044
1045 audio_io_handle_t srcOutput = getOutputForEffect();
1046 addOutput(output, outputDesc);
1047 audio_io_handle_t dstOutput = getOutputForEffect();
1048 if (dstOutput == output) {
1049 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
1050 }
1051 mPreviousOutputs = mOutputs;
1052 ALOGV("getOutput() returns new direct output %d", output);
1053 mpClientInterface->onAudioPortListUpdate();
1054 return output;
1055 }
1056
1057non_direct_output:
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001058 // ignoring channel mask due to downmix capability in mixer
1059
1060 // open a non direct output
1061
1062 // for non direct outputs, only PCM is supported
1063 if (audio_is_linear_pcm(format)) {
1064 // get which output is suitable for the specified stream. The actual
1065 // routing change will happen when startOutput() will be called
1066 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1067
1068 // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
1069 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
1070 output = selectOutput(outputs, flags, format);
1071 }
1072 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1073 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1074
Sharad Sanglef2e11662015-05-28 16:15:16 +05301075 ALOGV(" getOutputForDevice() returns output %d", output);
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001076
1077 return output;
1078}
Ravi Kumar Alamanda1cf2a592014-10-29 20:31:15 -07001079}