blob: 804a64b5545092502e1214eab20c4f7d02e06199 [file] [log] [blame]
Eric Laurente552edb2014-03-10 17:42:56 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -080017#define LOG_TAG "APM::AudioPolicyManager"
Eric Laurente552edb2014-03-10 17:42:56 -070018//#define LOG_NDEBUG 0
19
20//#define VERY_VERBOSE_LOGGING
21#ifdef VERY_VERBOSE_LOGGING
22#define ALOGVV ALOGV
23#else
24#define ALOGVV(a...) do { } while(0)
25#endif
26
Eric Laurentd4692962014-05-05 18:13:44 -070027#include <inttypes.h>
Eric Laurente552edb2014-03-10 17:42:56 -070028#include <math.h>
Eric Laurentd4692962014-05-05 18:13:44 -070029
François Gaffie2110e042015-03-24 08:41:51 +010030#include <AudioPolicyManagerInterface.h>
31#include <AudioPolicyEngineInstance.h>
Eric Laurente552edb2014-03-10 17:42:56 -070032#include <cutils/properties.h>
Eric Laurentd4692962014-05-05 18:13:44 -070033#include <utils/Log.h>
34#include <hardware/audio.h>
35#include <hardware/audio_effect.h>
Eric Laurent3b73df72014-03-11 09:06:29 -070036#include <media/AudioParameter.h>
Eric Laurente83b55d2014-11-14 10:06:21 -080037#include <media/AudioPolicyHelper.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070038#include <soundtrigger/SoundTrigger.h>
Eric Laurentd4692962014-05-05 18:13:44 -070039#include "AudioPolicyManager.h"
Eric Laurent1afeecb2014-05-14 08:52:28 -070040#include "audio_policy_conf.h"
François Gaffie53615e22015-03-19 09:24:12 +010041#include <ConfigParsingUtils.h>
42#include <policy.h>
Eric Laurente552edb2014-03-10 17:42:56 -070043
Eric Laurent3b73df72014-03-11 09:06:29 -070044namespace android {
Eric Laurente552edb2014-03-10 17:42:56 -070045
46// ----------------------------------------------------------------------------
47// AudioPolicyInterface implementation
48// ----------------------------------------------------------------------------
49
Eric Laurente0720872014-03-11 09:30:41 -070050status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
Paul McLeane743a472015-01-28 11:07:31 -080051 audio_policy_dev_state_t state,
52 const char *device_address,
53 const char *device_name)
Eric Laurente552edb2014-03-10 17:42:56 -070054{
Paul McLeane743a472015-01-28 11:07:31 -080055 return setDeviceConnectionStateInt(device, state, device_address, device_name);
Eric Laurentc73ca6e2014-12-12 14:34:22 -080056}
57
58status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
Eric Laurenta1d525f2015-01-29 13:36:45 -080059 audio_policy_dev_state_t state,
Paul McLeane743a472015-01-28 11:07:31 -080060 const char *device_address,
61 const char *device_name)
Eric Laurentc73ca6e2014-12-12 14:34:22 -080062{
Paul McLeane743a472015-01-28 11:07:31 -080063 ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
64- device, state, device_address, device_name);
Eric Laurente552edb2014-03-10 17:42:56 -070065
66 // connect/disconnect only 1 device at a time
67 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
68
François Gaffie53615e22015-03-19 09:24:12 +010069 sp<DeviceDescriptor> devDesc =
70 mHwModules.getDeviceDescriptor(device, device_address, device_name);
Paul McLeane743a472015-01-28 11:07:31 -080071
Eric Laurente552edb2014-03-10 17:42:56 -070072 // handle output devices
73 if (audio_is_output_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -070074 SortedVector <audio_io_handle_t> outputs;
75
Eric Laurent3a4311c2014-03-17 12:00:47 -070076 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
77
Eric Laurente552edb2014-03-10 17:42:56 -070078 // save a copy of the opened output descriptors before any output is opened or closed
79 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
80 mPreviousOutputs = mOutputs;
Eric Laurente552edb2014-03-10 17:42:56 -070081 switch (state)
82 {
83 // handle output device connection
Eric Laurent3ae5f312015-02-03 17:12:08 -080084 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -070085 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -070086 ALOGW("setDeviceConnectionState() device already connected: %x", device);
87 return INVALID_OPERATION;
88 }
89 ALOGV("setDeviceConnectionState() connecting device %x", device);
90
Eric Laurente552edb2014-03-10 17:42:56 -070091 // register new device as available
Eric Laurent3a4311c2014-03-17 12:00:47 -070092 index = mAvailableOutputDevices.add(devDesc);
93 if (index >= 0) {
François Gaffie53615e22015-03-19 09:24:12 +010094 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurentcf817a22014-08-04 20:36:31 -070095 if (module == 0) {
96 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
97 device);
98 mAvailableOutputDevices.remove(devDesc);
99 return INVALID_OPERATION;
100 }
Paul McLeane743a472015-01-28 11:07:31 -0800101 mAvailableOutputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700102 } else {
103 return NO_MEMORY;
Eric Laurente552edb2014-03-10 17:42:56 -0700104 }
105
Eric Laurenta1d525f2015-01-29 13:36:45 -0800106 if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700107 mAvailableOutputDevices.remove(devDesc);
108 return INVALID_OPERATION;
109 }
François Gaffie2110e042015-03-24 08:41:51 +0100110 // Propagate device availability to Engine
111 mEngine->setDeviceConnectionState(devDesc, state);
112
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700113 // outputs should never be empty here
114 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
115 "checkOutputsForDevice() returned no outputs but status OK");
116 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
117 outputs.size());
Eric Laurent3ae5f312015-02-03 17:12:08 -0800118
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -0800119 // Send connect to HALs
Eric Laurent3ae5f312015-02-03 17:12:08 -0800120 AudioParameter param = AudioParameter(devDesc->mAddress);
121 param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
122 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
123
124 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700125 // handle output device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700126 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700127 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700128 ALOGW("setDeviceConnectionState() device not connected: %x", device);
129 return INVALID_OPERATION;
130 }
131
Paul McLean5c477aa2014-08-20 16:47:57 -0700132 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
133
Paul McLeane743a472015-01-28 11:07:31 -0800134 // Send Disconnect to HALs
Eric Laurenta1d525f2015-01-29 13:36:45 -0800135 AudioParameter param = AudioParameter(devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700136 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
137 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
138
Eric Laurente552edb2014-03-10 17:42:56 -0700139 // remove device from available output devices
Eric Laurent3a4311c2014-03-17 12:00:47 -0700140 mAvailableOutputDevices.remove(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700141
Eric Laurenta1d525f2015-01-29 13:36:45 -0800142 checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
François Gaffie2110e042015-03-24 08:41:51 +0100143
144 // Propagate device availability to Engine
145 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurente552edb2014-03-10 17:42:56 -0700146 } break;
147
148 default:
149 ALOGE("setDeviceConnectionState() invalid state: %x", state);
150 return BAD_VALUE;
151 }
152
Eric Laurent3a4311c2014-03-17 12:00:47 -0700153 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
154 // output is suspended before any tracks are moved to it
Eric Laurente552edb2014-03-10 17:42:56 -0700155 checkA2dpSuspend();
156 checkOutputForAllStrategies();
157 // outputs must be closed after checkOutputForAllStrategies() is executed
158 if (!outputs.isEmpty()) {
159 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700160 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -0700161 // close unused outputs after device disconnection or direct outputs that have been
162 // opened by checkOutputsForDevice() to query dynamic parameters
Eric Laurent3b73df72014-03-11 09:06:29 -0700163 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Eric Laurente552edb2014-03-10 17:42:56 -0700164 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
165 (desc->mDirectOpenCount == 0))) {
166 closeOutput(outputs[i]);
167 }
168 }
Eric Laurent3a4311c2014-03-17 12:00:47 -0700169 // check again after closing A2DP output to reset mA2dpSuspended if needed
170 checkA2dpSuspend();
Eric Laurente552edb2014-03-10 17:42:56 -0700171 }
172
173 updateDevicesAndOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100174 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700175 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
176 updateCallRouting(newDevice);
177 }
Eric Laurente552edb2014-03-10 17:42:56 -0700178 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700179 audio_io_handle_t output = mOutputs.keyAt(i);
François Gaffie2110e042015-03-24 08:41:51 +0100180 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700181 audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i),
182 true /*fromCache*/);
183 // do not force device change on duplicated output because if device is 0, it will
184 // also force a device 0 for the two outputs it is duplicated to which may override
185 // a valid device selection on those outputs.
186 bool force = !mOutputs.valueAt(i)->isDuplicated()
François Gaffie53615e22015-03-19 09:24:12 +0100187 && (!device_distinguishes_on_address(device)
Eric Laurentc2730ba2014-07-20 15:47:07 -0700188 // always force when disconnecting (a non-duplicated device)
189 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
190 setOutputDevice(output, newDevice, force, 0);
191 }
Eric Laurente552edb2014-03-10 17:42:56 -0700192 }
193
Eric Laurent72aa32f2014-05-30 18:51:48 -0700194 mpClientInterface->onAudioPortListUpdate();
Eric Laurentb71e58b2014-05-29 16:08:11 -0700195 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700196 } // end if is output device
197
Eric Laurente552edb2014-03-10 17:42:56 -0700198 // handle input devices
199 if (audio_is_input_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700200 SortedVector <audio_io_handle_t> inputs;
201
Eric Laurent3a4311c2014-03-17 12:00:47 -0700202 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700203 switch (state)
204 {
205 // handle input device connection
Eric Laurent3b73df72014-03-11 09:06:29 -0700206 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700207 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700208 ALOGW("setDeviceConnectionState() device already connected: %d", device);
209 return INVALID_OPERATION;
210 }
François Gaffie53615e22015-03-19 09:24:12 +0100211 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurent6a94d692014-05-20 11:18:06 -0700212 if (module == NULL) {
213 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
214 device);
215 return INVALID_OPERATION;
216 }
Eric Laurenta1d525f2015-01-29 13:36:45 -0800217 if (checkInputsForDevice(device, state, inputs, devDesc->mAddress) != NO_ERROR) {
Eric Laurentd4692962014-05-05 18:13:44 -0700218 return INVALID_OPERATION;
219 }
220
Eric Laurent3a4311c2014-03-17 12:00:47 -0700221 index = mAvailableInputDevices.add(devDesc);
222 if (index >= 0) {
Paul McLeane743a472015-01-28 11:07:31 -0800223 mAvailableInputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700224 } else {
225 return NO_MEMORY;
226 }
Eric Laurent3ae5f312015-02-03 17:12:08 -0800227
228 // Set connect to HALs
229 AudioParameter param = AudioParameter(devDesc->mAddress);
230 param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
231 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
232
François Gaffie2110e042015-03-24 08:41:51 +0100233 // Propagate device availability to Engine
234 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700235 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700236
237 // handle input device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700238 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700239 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700240 ALOGW("setDeviceConnectionState() device not connected: %d", device);
241 return INVALID_OPERATION;
242 }
Paul McLean5c477aa2014-08-20 16:47:57 -0700243
244 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
245
246 // Set Disconnect to HALs
Eric Laurenta1d525f2015-01-29 13:36:45 -0800247 AudioParameter param = AudioParameter(devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700248 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
249 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
250
Eric Laurenta1d525f2015-01-29 13:36:45 -0800251 checkInputsForDevice(device, state, inputs, devDesc->mAddress);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700252 mAvailableInputDevices.remove(devDesc);
Paul McLean5c477aa2014-08-20 16:47:57 -0700253
François Gaffie2110e042015-03-24 08:41:51 +0100254 // Propagate device availability to Engine
255 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700256 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700257
258 default:
259 ALOGE("setDeviceConnectionState() invalid state: %x", state);
260 return BAD_VALUE;
261 }
262
Eric Laurentd4692962014-05-05 18:13:44 -0700263 closeAllInputs();
Eric Laurente552edb2014-03-10 17:42:56 -0700264
François Gaffie2110e042015-03-24 08:41:51 +0100265 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700266 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
267 updateCallRouting(newDevice);
268 }
269
Eric Laurentb52c1522014-05-20 11:27:36 -0700270 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700271 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700272 } // end if is input device
Eric Laurente552edb2014-03-10 17:42:56 -0700273
274 ALOGW("setDeviceConnectionState() invalid device: %x", device);
275 return BAD_VALUE;
276}
277
Eric Laurente0720872014-03-11 09:30:41 -0700278audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +0100279 const char *device_address)
Eric Laurente552edb2014-03-10 17:42:56 -0700280{
François Gaffie53615e22015-03-19 09:24:12 +0100281 sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(device, device_address, "");
282
Eric Laurent3a4311c2014-03-17 12:00:47 -0700283 DeviceVector *deviceVector;
284
Eric Laurente552edb2014-03-10 17:42:56 -0700285 if (audio_is_output_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700286 deviceVector = &mAvailableOutputDevices;
Eric Laurente552edb2014-03-10 17:42:56 -0700287 } else if (audio_is_input_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700288 deviceVector = &mAvailableInputDevices;
289 } else {
290 ALOGW("getDeviceConnectionState() invalid device type %08x", device);
291 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurente552edb2014-03-10 17:42:56 -0700292 }
François Gaffie53615e22015-03-19 09:24:12 +0100293 return deviceVector->getDeviceConnectionState(devDesc);
Eric Laurenta1d525f2015-01-29 13:36:45 -0800294}
295
Eric Laurentc2730ba2014-07-20 15:47:07 -0700296void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)
297{
298 bool createTxPatch = false;
299 struct audio_patch patch;
300 patch.num_sources = 1;
301 patch.num_sinks = 1;
302 status_t status;
303 audio_patch_handle_t afPatchHandle;
304 DeviceVector deviceList;
305
Eric Laurentc73ca6e2014-12-12 14:34:22 -0800306 audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700307 ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
308
309 // release existing RX patch if any
310 if (mCallRxPatch != 0) {
311 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
312 mCallRxPatch.clear();
313 }
314 // release TX patch if any
315 if (mCallTxPatch != 0) {
316 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
317 mCallTxPatch.clear();
318 }
319
320 // If the RX device is on the primary HW module, then use legacy routing method for voice calls
321 // via setOutputDevice() on primary output.
322 // Otherwise, create two audio patches for TX and RX path.
323 if (availablePrimaryOutputDevices() & rxDevice) {
324 setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
325 // If the TX device is also on the primary HW module, setOutputDevice() will take care
326 // of it due to legacy implementation. If not, create a patch.
327 if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
328 == AUDIO_DEVICE_NONE) {
329 createTxPatch = true;
330 }
331 } else {
332 // create RX path audio patch
333 deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
334 ALOG_ASSERT(!deviceList.isEmpty(),
335 "updateCallRouting() selected device not in output device list");
336 sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
337 deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
338 ALOG_ASSERT(!deviceList.isEmpty(),
339 "updateCallRouting() no telephony RX device");
340 sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
341
342 rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
343 rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
344
345 // request to reuse existing output stream if one is already opened to reach the RX device
346 SortedVector<audio_io_handle_t> outputs =
347 getOutputsForDevice(rxDevice, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700348 audio_io_handle_t output = selectOutput(outputs,
349 AUDIO_OUTPUT_FLAG_NONE,
350 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700351 if (output != AUDIO_IO_HANDLE_NONE) {
352 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
353 ALOG_ASSERT(!outputDesc->isDuplicated(),
354 "updateCallRouting() RX device output is duplicated");
355 outputDesc->toAudioPortConfig(&patch.sources[1]);
356 patch.num_sources = 2;
357 }
358
359 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
360 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
361 ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
362 status);
363 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100364 mCallRxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700365 mCallRxPatch->mAfPatchHandle = afPatchHandle;
366 mCallRxPatch->mUid = mUidCached;
367 }
368 createTxPatch = true;
369 }
370 if (createTxPatch) {
371
372 struct audio_patch patch;
373 patch.num_sources = 1;
374 patch.num_sinks = 1;
375 deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
376 ALOG_ASSERT(!deviceList.isEmpty(),
377 "updateCallRouting() selected device not in input device list");
378 sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
379 txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
380 deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
381 ALOG_ASSERT(!deviceList.isEmpty(),
382 "updateCallRouting() no telephony TX device");
383 sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
384 txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
385
386 SortedVector<audio_io_handle_t> outputs =
387 getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700388 audio_io_handle_t output = selectOutput(outputs,
389 AUDIO_OUTPUT_FLAG_NONE,
390 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700391 // request to reuse existing output stream if one is already opened to reach the TX
392 // path output device
393 if (output != AUDIO_IO_HANDLE_NONE) {
394 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
395 ALOG_ASSERT(!outputDesc->isDuplicated(),
396 "updateCallRouting() RX device output is duplicated");
397 outputDesc->toAudioPortConfig(&patch.sources[1]);
398 patch.num_sources = 2;
399 }
400
401 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
402 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
403 ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
404 status);
405 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100406 mCallTxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700407 mCallTxPatch->mAfPatchHandle = afPatchHandle;
408 mCallTxPatch->mUid = mUidCached;
409 }
410 }
411}
412
Eric Laurente0720872014-03-11 09:30:41 -0700413void AudioPolicyManager::setPhoneState(audio_mode_t state)
Eric Laurente552edb2014-03-10 17:42:56 -0700414{
415 ALOGV("setPhoneState() state %d", state);
François Gaffie2110e042015-03-24 08:41:51 +0100416 // store previous phone state for management of sonification strategy below
417 int oldState = mEngine->getPhoneState();
418
419 if (mEngine->setPhoneState(state) != NO_ERROR) {
420 ALOGW("setPhoneState() invalid or same state %d", state);
Eric Laurente552edb2014-03-10 17:42:56 -0700421 return;
422 }
François Gaffie2110e042015-03-24 08:41:51 +0100423 /// Opens: can these line be executed after the switch of volume curves???
Eric Laurente552edb2014-03-10 17:42:56 -0700424 // if leaving call state, handle special case of active streams
425 // pertaining to sonification strategy see handleIncallSonification()
426 if (isInCall()) {
427 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700428 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -0800429 if (stream == AUDIO_STREAM_PATCH) {
430 continue;
431 }
Eric Laurent3b73df72014-03-11 09:06:29 -0700432 handleIncallSonification((audio_stream_type_t)stream, false, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700433 }
Eric Laurent2cbe89a2014-12-19 11:49:08 -0800434
435 // force reevaluating accessibility routing when call starts
436 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -0700437 }
438
François Gaffie2110e042015-03-24 08:41:51 +0100439 /**
440 * Switching to or from incall state or switching between telephony and VoIP lead to force
441 * routing command.
442 */
443 bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
444 || (is_state_in_call(state) && (state != oldState)));
Eric Laurente552edb2014-03-10 17:42:56 -0700445
446 // check for device and output changes triggered by new phone state
Eric Laurente552edb2014-03-10 17:42:56 -0700447 checkA2dpSuspend();
448 checkOutputForAllStrategies();
449 updateDevicesAndOutputs();
450
Eric Laurent1f2f2232014-06-02 12:01:23 -0700451 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -0700452
Eric Laurente552edb2014-03-10 17:42:56 -0700453 int delayMs = 0;
454 if (isStateInCall(state)) {
455 nsecs_t sysTime = systemTime();
456 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700457 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700458 // mute media and sonification strategies and delay device switch by the largest
459 // latency of any output where either strategy is active.
460 // This avoid sending the ring tone or music tail into the earpiece or headset.
François Gaffiead3183e2015-03-18 16:55:35 +0100461 if ((isStrategyActive(desc, STRATEGY_MEDIA,
462 SONIFICATION_HEADSET_MUSIC_DELAY,
463 sysTime) ||
464 isStrategyActive(desc, STRATEGY_SONIFICATION,
465 SONIFICATION_HEADSET_MUSIC_DELAY,
466 sysTime)) &&
Eric Laurente552edb2014-03-10 17:42:56 -0700467 (delayMs < (int)desc->mLatency*2)) {
468 delayMs = desc->mLatency*2;
469 }
470 setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
471 setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
472 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
473 setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
474 setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
475 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
476 }
477 }
478
Eric Laurentc2730ba2014-07-20 15:47:07 -0700479 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
480 // the device returned is not necessarily reachable via this output
481 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
482 // force routing command to audio hardware when ending call
483 // even if no device change is needed
484 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
485 rxDevice = hwOutputDesc->device();
486 }
Eric Laurente552edb2014-03-10 17:42:56 -0700487
Eric Laurentc2730ba2014-07-20 15:47:07 -0700488 if (state == AUDIO_MODE_IN_CALL) {
489 updateCallRouting(rxDevice, delayMs);
490 } else if (oldState == AUDIO_MODE_IN_CALL) {
491 if (mCallRxPatch != 0) {
492 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
493 mCallRxPatch.clear();
494 }
495 if (mCallTxPatch != 0) {
496 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
497 mCallTxPatch.clear();
498 }
499 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
500 } else {
501 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
502 }
Eric Laurente552edb2014-03-10 17:42:56 -0700503 // if entering in call state, handle special case of active streams
504 // pertaining to sonification strategy see handleIncallSonification()
505 if (isStateInCall(state)) {
506 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700507 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -0800508 if (stream == AUDIO_STREAM_PATCH) {
509 continue;
510 }
Eric Laurent3b73df72014-03-11 09:06:29 -0700511 handleIncallSonification((audio_stream_type_t)stream, true, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700512 }
513 }
514
515 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
Eric Laurent3b73df72014-03-11 09:06:29 -0700516 if (state == AUDIO_MODE_RINGTONE &&
517 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700518 mLimitRingtoneVolume = true;
519 } else {
520 mLimitRingtoneVolume = false;
521 }
522}
523
Jean-Michel Trivi887a9ed2015-03-31 18:02:24 -0700524audio_mode_t AudioPolicyManager::getPhoneState() {
525 return mEngine->getPhoneState();
526}
527
Eric Laurente0720872014-03-11 09:30:41 -0700528void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
Eric Laurent3b73df72014-03-11 09:06:29 -0700529 audio_policy_forced_cfg_t config)
Eric Laurente552edb2014-03-10 17:42:56 -0700530{
François Gaffie2110e042015-03-24 08:41:51 +0100531 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
Eric Laurente552edb2014-03-10 17:42:56 -0700532
François Gaffie2110e042015-03-24 08:41:51 +0100533 if (mEngine->setForceUse(usage, config) != NO_ERROR) {
534 ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
535 return;
Eric Laurente552edb2014-03-10 17:42:56 -0700536 }
François Gaffie2110e042015-03-24 08:41:51 +0100537 bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
538 (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
539 (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
Eric Laurente552edb2014-03-10 17:42:56 -0700540
541 // check for device and output changes triggered by new force usage
542 checkA2dpSuspend();
543 checkOutputForAllStrategies();
544 updateDevicesAndOutputs();
François Gaffie2110e042015-03-24 08:41:51 +0100545 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700546 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
547 updateCallRouting(newDevice);
548 }
Eric Laurente552edb2014-03-10 17:42:56 -0700549 for (size_t i = 0; i < mOutputs.size(); i++) {
550 audio_io_handle_t output = mOutputs.keyAt(i);
Eric Laurent1c333e22014-05-20 10:48:17 -0700551 audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
François Gaffie2110e042015-03-24 08:41:51 +0100552 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700553 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
554 }
Eric Laurente552edb2014-03-10 17:42:56 -0700555 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
556 applyStreamVolumes(output, newDevice, 0, true);
557 }
558 }
559
François Gaffie53615e22015-03-19 09:24:12 +0100560 audio_io_handle_t activeInput = mInputs.getActiveInput();
Eric Laurente552edb2014-03-10 17:42:56 -0700561 if (activeInput != 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700562 setInputDevice(activeInput, getNewInputDevice(activeInput));
Eric Laurente552edb2014-03-10 17:42:56 -0700563 }
564
565}
566
Eric Laurente0720872014-03-11 09:30:41 -0700567void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
Eric Laurente552edb2014-03-10 17:42:56 -0700568{
569 ALOGV("setSystemProperty() property %s, value %s", property, value);
570}
571
572// Find a direct output profile compatible with the parameters passed, even if the input flags do
573// not explicitly request a direct output
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -0800574sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
Eric Laurente552edb2014-03-10 17:42:56 -0700575 audio_devices_t device,
576 uint32_t samplingRate,
577 audio_format_t format,
578 audio_channel_mask_t channelMask,
579 audio_output_flags_t flags)
580{
581 for (size_t i = 0; i < mHwModules.size(); i++) {
582 if (mHwModules[i]->mHandle == 0) {
583 continue;
584 }
585 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700586 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
Eric Laurent275e8e92014-11-30 15:14:47 -0800587 bool found = profile->isCompatibleProfile(device, String8(""), samplingRate,
Glenn Kastencbd48022014-07-24 13:46:44 -0700588 NULL /*updatedSamplingRate*/, format, channelMask,
589 flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ?
590 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700591 if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
592 return profile;
593 }
Eric Laurente552edb2014-03-10 17:42:56 -0700594 }
595 }
596 return 0;
597}
598
Eric Laurente0720872014-03-11 09:30:41 -0700599audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +0100600 uint32_t samplingRate,
601 audio_format_t format,
602 audio_channel_mask_t channelMask,
603 audio_output_flags_t flags,
604 const audio_offload_info_t *offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -0700605{
Eric Laurent3b73df72014-03-11 09:06:29 -0700606 routing_strategy strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -0700607 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
608 ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
609 device, stream, samplingRate, format, channelMask, flags);
610
Eric Laurente83b55d2014-11-14 10:06:21 -0800611 return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE,
612 stream, samplingRate,format, channelMask,
613 flags, offloadInfo);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700614}
615
Eric Laurente83b55d2014-11-14 10:06:21 -0800616status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
617 audio_io_handle_t *output,
618 audio_session_t session,
619 audio_stream_type_t *stream,
620 uint32_t samplingRate,
621 audio_format_t format,
622 audio_channel_mask_t channelMask,
623 audio_output_flags_t flags,
Paul McLeanaa981192015-03-21 09:55:15 -0700624 audio_port_handle_t selectedDeviceId,
Eric Laurente83b55d2014-11-14 10:06:21 -0800625 const audio_offload_info_t *offloadInfo)
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700626{
Eric Laurente83b55d2014-11-14 10:06:21 -0800627 audio_attributes_t attributes;
628 if (attr != NULL) {
629 if (!isValidAttributes(attr)) {
630 ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
631 attr->usage, attr->content_type, attr->flags,
632 attr->tags);
633 return BAD_VALUE;
634 }
635 attributes = *attr;
636 } else {
637 if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
638 ALOGE("getOutputForAttr(): invalid stream type");
639 return BAD_VALUE;
640 }
641 stream_type_to_audio_attributes(*stream, &attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700642 }
François Gaffie036e1e92015-03-19 10:16:24 +0100643 sp<AudioOutputDescriptor> desc;
644 if (mPolicyMixes.getOutputForAttr(attributes, desc) == NO_ERROR) {
645 ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
646 if (!audio_is_linear_pcm(format)) {
647 return BAD_VALUE;
Eric Laurent275e8e92014-11-30 15:14:47 -0800648 }
François Gaffie036e1e92015-03-19 10:16:24 +0100649 *stream = streamTypefromAttributesInt(&attributes);
650 *output = desc->mIoHandle;
651 ALOGV("getOutputForAttr() returns output %d", *output);
652 return NO_ERROR;
Eric Laurent275e8e92014-11-30 15:14:47 -0800653 }
654 if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
655 ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
656 return BAD_VALUE;
657 }
658
Eric Laurent93c3d412014-08-01 14:48:35 -0700659 ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x",
François Gaffie53615e22015-03-19 09:24:12 +0100660 attributes.usage, attributes.content_type, attributes.tags, attributes.flags);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700661
Eric Laurente83b55d2014-11-14 10:06:21 -0800662 routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700663 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
Eric Laurent93c3d412014-08-01 14:48:35 -0700664
Eric Laurente83b55d2014-11-14 10:06:21 -0800665 if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
Eric Laurent93c3d412014-08-01 14:48:35 -0700666 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
667 }
668
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -0700669 ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700670 device, samplingRate, format, channelMask, flags);
671
Eric Laurente83b55d2014-11-14 10:06:21 -0800672 *stream = streamTypefromAttributesInt(&attributes);
673 *output = getOutputForDevice(device, session, *stream,
674 samplingRate, format, channelMask,
675 flags, offloadInfo);
676 if (*output == AUDIO_IO_HANDLE_NONE) {
677 return INVALID_OPERATION;
678 }
Paul McLeanaa981192015-03-21 09:55:15 -0700679
680 // Explicit routing?
681 sp<DeviceDescriptor> deviceDesc;
682
683 for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
684 if (mAvailableOutputDevices[i]->getHandle() == selectedDeviceId) {
685 deviceDesc = mAvailableOutputDevices[i];
686 break;
687 }
688 }
689 mOutputRoutes.addRoute(session, *stream, deviceDesc);
Eric Laurente83b55d2014-11-14 10:06:21 -0800690 return NO_ERROR;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700691}
692
693audio_io_handle_t AudioPolicyManager::getOutputForDevice(
694 audio_devices_t device,
Eric Laurentcaf7f482014-11-25 17:50:47 -0800695 audio_session_t session __unused,
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700696 audio_stream_type_t stream,
697 uint32_t samplingRate,
698 audio_format_t format,
699 audio_channel_mask_t channelMask,
700 audio_output_flags_t flags,
701 const audio_offload_info_t *offloadInfo)
702{
Eric Laurentcf2c0212014-07-25 16:20:43 -0700703 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700704 uint32_t latency = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700705 status_t status;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700706
Eric Laurente552edb2014-03-10 17:42:56 -0700707#ifdef AUDIO_POLICY_TEST
708 if (mCurOutput != 0) {
709 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
710 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
711
712 if (mTestOutputs[mCurOutput] == 0) {
713 ALOGV("getOutput() opening test output");
Eric Laurent1f2f2232014-06-02 12:01:23 -0700714 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
Eric Laurente552edb2014-03-10 17:42:56 -0700715 outputDesc->mDevice = mTestDevice;
Eric Laurente552edb2014-03-10 17:42:56 -0700716 outputDesc->mLatency = mTestLatencyMs;
Eric Laurent3b73df72014-03-11 09:06:29 -0700717 outputDesc->mFlags =
718 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
Eric Laurente552edb2014-03-10 17:42:56 -0700719 outputDesc->mRefCount[stream] = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700720 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
721 config.sample_rate = mTestSamplingRate;
722 config.channel_mask = mTestChannels;
723 config.format = mTestFormat;
Phil Burk77cce802014-08-04 16:18:15 -0700724 if (offloadInfo != NULL) {
725 config.offload_info = *offloadInfo;
726 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700727 status = mpClientInterface->openOutput(0,
728 &mTestOutputs[mCurOutput],
729 &config,
730 &outputDesc->mDevice,
731 String8(""),
732 &outputDesc->mLatency,
733 outputDesc->mFlags);
734 if (status == NO_ERROR) {
735 outputDesc->mSamplingRate = config.sample_rate;
736 outputDesc->mFormat = config.format;
737 outputDesc->mChannelMask = config.channel_mask;
Eric Laurente552edb2014-03-10 17:42:56 -0700738 AudioParameter outputCmd = AudioParameter();
739 outputCmd.addInt(String8("set_id"),mCurOutput);
740 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
741 addOutput(mTestOutputs[mCurOutput], outputDesc);
742 }
743 }
744 return mTestOutputs[mCurOutput];
745 }
746#endif //AUDIO_POLICY_TEST
747
748 // open a direct output if required by specified parameters
749 //force direct flag if offload flag is set: offloading implies a direct output stream
750 // and all common behaviors are driven by checking only the direct flag
751 // this should normally be set appropriately in the policy configuration file
752 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700753 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurente552edb2014-03-10 17:42:56 -0700754 }
Eric Laurent93c3d412014-08-01 14:48:35 -0700755 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
756 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
757 }
Eric Laurente83b55d2014-11-14 10:06:21 -0800758 // only allow deep buffering for music stream type
759 if (stream != AUDIO_STREAM_MUSIC) {
760 flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
761 }
Eric Laurente552edb2014-03-10 17:42:56 -0700762
Eric Laurentb732cf52014-09-24 19:08:21 -0700763 sp<IOProfile> profile;
764
765 // skip direct output selection if the request can obviously be attached to a mixed output
Eric Laurentc2607842014-09-29 09:43:03 -0700766 // and not explicitly requested
767 if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
768 audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
Eric Laurentb732cf52014-09-24 19:08:21 -0700769 audio_channel_count_from_out_mask(channelMask) <= 2) {
770 goto non_direct_output;
771 }
772
Eric Laurente552edb2014-03-10 17:42:56 -0700773 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
774 // creating an offloaded track and tearing it down immediately after start when audioflinger
775 // detects there is an active non offloadable effect.
776 // FIXME: We should check the audio session here but we do not have it in this context.
777 // This may prevent offloading in rare situations where effects are left active by apps
778 // in the background.
Eric Laurentb732cf52014-09-24 19:08:21 -0700779
Eric Laurente552edb2014-03-10 17:42:56 -0700780 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
François Gaffie45ed3b02015-03-19 10:35:14 +0100781 !mEffects.isNonOffloadableEffectEnabled()) {
Eric Laurente552edb2014-03-10 17:42:56 -0700782 profile = getProfileForDirectOutput(device,
783 samplingRate,
784 format,
785 channelMask,
786 (audio_output_flags_t)flags);
787 }
788
Eric Laurent1c333e22014-05-20 10:48:17 -0700789 if (profile != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700790 sp<AudioOutputDescriptor> outputDesc = NULL;
Eric Laurente552edb2014-03-10 17:42:56 -0700791
792 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700793 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700794 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
795 outputDesc = desc;
796 // reuse direct output if currently open and configured with same parameters
797 if ((samplingRate == outputDesc->mSamplingRate) &&
798 (format == outputDesc->mFormat) &&
799 (channelMask == outputDesc->mChannelMask)) {
800 outputDesc->mDirectOpenCount++;
801 ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
802 return mOutputs.keyAt(i);
803 }
804 }
805 }
806 // close direct output if currently open and configured with different parameters
807 if (outputDesc != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700808 closeOutput(outputDesc->mIoHandle);
Eric Laurente552edb2014-03-10 17:42:56 -0700809 }
810 outputDesc = new AudioOutputDescriptor(profile);
811 outputDesc->mDevice = device;
Eric Laurente552edb2014-03-10 17:42:56 -0700812 outputDesc->mLatency = 0;
813 outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700814 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
815 config.sample_rate = samplingRate;
816 config.channel_mask = channelMask;
817 config.format = format;
Phil Burk77cce802014-08-04 16:18:15 -0700818 if (offloadInfo != NULL) {
819 config.offload_info = *offloadInfo;
820 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700821 status = mpClientInterface->openOutput(profile->mModule->mHandle,
822 &output,
823 &config,
824 &outputDesc->mDevice,
825 String8(""),
826 &outputDesc->mLatency,
827 outputDesc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -0700828
829 // only accept an output with the requested parameters
Eric Laurentcf2c0212014-07-25 16:20:43 -0700830 if (status != NO_ERROR ||
831 (samplingRate != 0 && samplingRate != config.sample_rate) ||
832 (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
833 (channelMask != 0 && channelMask != config.channel_mask)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700834 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
835 "format %d %d, channelMask %04x %04x", output, samplingRate,
836 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
837 outputDesc->mChannelMask);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700838 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -0700839 mpClientInterface->closeOutput(output);
840 }
Eric Laurenta82797f2015-01-30 11:49:43 -0800841 // fall back to mixer output if possible when the direct output could not be open
842 if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
843 goto non_direct_output;
844 }
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -0800845 // fall back to mixer output if possible when the direct output could not be open
846 if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
847 goto non_direct_output;
848 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700849 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -0700850 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700851 outputDesc->mSamplingRate = config.sample_rate;
852 outputDesc->mChannelMask = config.channel_mask;
853 outputDesc->mFormat = config.format;
854 outputDesc->mRefCount[stream] = 0;
855 outputDesc->mStopTime[stream] = 0;
856 outputDesc->mDirectOpenCount = 1;
857
Eric Laurente552edb2014-03-10 17:42:56 -0700858 audio_io_handle_t srcOutput = getOutputForEffect();
859 addOutput(output, outputDesc);
860 audio_io_handle_t dstOutput = getOutputForEffect();
861 if (dstOutput == output) {
862 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
863 }
864 mPreviousOutputs = mOutputs;
865 ALOGV("getOutput() returns new direct output %d", output);
Eric Laurentb52c1522014-05-20 11:27:36 -0700866 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700867 return output;
868 }
869
Eric Laurentb732cf52014-09-24 19:08:21 -0700870non_direct_output:
Eric Laurente552edb2014-03-10 17:42:56 -0700871 // ignoring channel mask due to downmix capability in mixer
872
873 // open a non direct output
874
875 // for non direct outputs, only PCM is supported
876 if (audio_is_linear_pcm(format)) {
877 // get which output is suitable for the specified stream. The actual
878 // routing change will happen when startOutput() will be called
879 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
880
Eric Laurent8838a382014-09-08 16:44:28 -0700881 // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
882 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
883 output = selectOutput(outputs, flags, format);
Eric Laurente552edb2014-03-10 17:42:56 -0700884 }
885 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
886 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
887
Paul McLeanaa981192015-03-21 09:55:15 -0700888 ALOGV(" getOutputForDevice() returns output %d", output);
Eric Laurente552edb2014-03-10 17:42:56 -0700889
890 return output;
891}
892
Eric Laurente0720872014-03-11 09:30:41 -0700893audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
Eric Laurent8838a382014-09-08 16:44:28 -0700894 audio_output_flags_t flags,
895 audio_format_t format)
Eric Laurente552edb2014-03-10 17:42:56 -0700896{
897 // select one output among several that provide a path to a particular device or set of
898 // devices (the list was previously build by getOutputsForDevice()).
899 // The priority is as follows:
900 // 1: the output with the highest number of requested policy flags
901 // 2: the primary output
902 // 3: the first output in the list
903
904 if (outputs.size() == 0) {
905 return 0;
906 }
907 if (outputs.size() == 1) {
908 return outputs[0];
909 }
910
911 int maxCommonFlags = 0;
912 audio_io_handle_t outputFlags = 0;
913 audio_io_handle_t outputPrimary = 0;
914
915 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700916 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -0700917 if (!outputDesc->isDuplicated()) {
Eric Laurent8838a382014-09-08 16:44:28 -0700918 // if a valid format is specified, skip output if not compatible
919 if (format != AUDIO_FORMAT_INVALID) {
920 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
921 if (format != outputDesc->mFormat) {
922 continue;
923 }
924 } else if (!audio_is_linear_pcm(format)) {
925 continue;
926 }
927 }
928
Eric Laurent3b73df72014-03-11 09:06:29 -0700929 int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
Eric Laurente552edb2014-03-10 17:42:56 -0700930 if (commonFlags > maxCommonFlags) {
931 outputFlags = outputs[i];
932 maxCommonFlags = commonFlags;
933 ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
934 }
935 if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
936 outputPrimary = outputs[i];
937 }
938 }
939 }
940
941 if (outputFlags != 0) {
942 return outputFlags;
943 }
944 if (outputPrimary != 0) {
945 return outputPrimary;
946 }
947
948 return outputs[0];
949}
950
Eric Laurente0720872014-03-11 09:30:41 -0700951status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -0700952 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -0800953 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -0700954{
Paul McLeanaa981192015-03-21 09:55:15 -0700955 ALOGV("startOutput() output %d, stream %d, session %d",
956 output, stream, session);
Eric Laurente552edb2014-03-10 17:42:56 -0700957 ssize_t index = mOutputs.indexOfKey(output);
958 if (index < 0) {
959 ALOGW("startOutput() unknown output %d", output);
960 return BAD_VALUE;
961 }
962
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -0700963 // cannot start playback of STREAM_TTS if any other output is being used
964 uint32_t beaconMuteLatency = 0;
965 if (stream == AUDIO_STREAM_TTS) {
966 ALOGV("\t found BEACON stream");
François Gaffie53615e22015-03-19 09:24:12 +0100967 if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -0700968 return INVALID_OPERATION;
969 } else {
970 beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
971 }
972 } else {
973 // some playback other than beacon starts
974 beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
975 }
976
Eric Laurent1f2f2232014-06-02 12:01:23 -0700977 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -0700978 // increment usage count for this stream on the requested output:
979 // NOTE that the usage count is the same for duplicated output and hardware output which is
980 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
981 outputDesc->changeRefCount(stream, 1);
982
Paul McLeanaa981192015-03-21 09:55:15 -0700983 // Routing?
984 mOutputRoutes.incRouteActivity(session);
985
Eric Laurente552edb2014-03-10 17:42:56 -0700986 if (outputDesc->mRefCount[stream] == 1) {
Eric Laurent275e8e92014-11-30 15:14:47 -0800987 // starting an output being rerouted?
988 audio_devices_t newDevice;
Eric Laurentc722f302014-12-10 11:21:49 -0800989 if (outputDesc->mPolicyMix != NULL) {
Eric Laurent275e8e92014-11-30 15:14:47 -0800990 newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
991 } else {
992 newDevice = getNewOutputDevice(output, false /*fromCache*/);
993 }
Eric Laurente552edb2014-03-10 17:42:56 -0700994 routing_strategy strategy = getStrategy(stream);
995 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -0700996 (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
997 (beaconMuteLatency > 0);
998 uint32_t waitMs = beaconMuteLatency;
Eric Laurente552edb2014-03-10 17:42:56 -0700999 bool force = false;
1000 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001001 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001002 if (desc != outputDesc) {
1003 // force a device change if any other output is managed by the same hw
1004 // module and has a current device selection that differs from selected device.
1005 // In this case, the audio HAL must receive the new device selection so that it can
1006 // change the device currently selected by the other active output.
1007 if (outputDesc->sharesHwModuleWith(desc) &&
1008 desc->device() != newDevice) {
1009 force = true;
1010 }
1011 // wait for audio on other active outputs to be presented when starting
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001012 // a notification so that audio focus effect can propagate, or that a mute/unmute
1013 // event occurred for beacon
Eric Laurente552edb2014-03-10 17:42:56 -07001014 uint32_t latency = desc->latency();
1015 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1016 waitMs = latency;
1017 }
1018 }
1019 }
1020 uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
1021
1022 // handle special case for sonification while in call
1023 if (isInCall()) {
1024 handleIncallSonification(stream, true, false);
1025 }
1026
1027 // apply volume rules for current stream and device if necessary
1028 checkAndSetVolume(stream,
1029 mStreams[stream].getVolumeIndex(newDevice),
1030 output,
1031 newDevice);
1032
1033 // update the outputs if starting an output with a stream that can affect notification
1034 // routing
1035 handleNotificationRoutingForStream(stream);
Eric Laurentc722f302014-12-10 11:21:49 -08001036
1037 // Automatically enable the remote submix input when output is started on a re routing mix
1038 // of type MIX_TYPE_RECORDERS
1039 if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL &&
1040 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001041 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001042 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001043 outputDesc->mPolicyMix->mRegistrationId,
1044 "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001045 }
1046
Eric Laurent2cbe89a2014-12-19 11:49:08 -08001047 // force reevaluating accessibility routing when ringtone or alarm starts
1048 if (strategy == STRATEGY_SONIFICATION) {
1049 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
1050 }
1051
Eric Laurente552edb2014-03-10 17:42:56 -07001052 if (waitMs > muteWaitMs) {
1053 usleep((waitMs - muteWaitMs) * 2 * 1000);
1054 }
1055 }
1056 return NO_ERROR;
1057}
1058
1059
Eric Laurente0720872014-03-11 09:30:41 -07001060status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001061 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -08001062 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001063{
1064 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1065 ssize_t index = mOutputs.indexOfKey(output);
1066 if (index < 0) {
1067 ALOGW("stopOutput() unknown output %d", output);
1068 return BAD_VALUE;
1069 }
1070
Eric Laurent1f2f2232014-06-02 12:01:23 -07001071 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001072
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001073 // always handle stream stop, check which stream type is stopping
1074 handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1075
Eric Laurente552edb2014-03-10 17:42:56 -07001076 // handle special case for sonification while in call
1077 if (isInCall()) {
1078 handleIncallSonification(stream, false, false);
1079 }
1080
1081 if (outputDesc->mRefCount[stream] > 0) {
1082 // decrement usage count of this stream on the output
1083 outputDesc->changeRefCount(stream, -1);
Paul McLeanaa981192015-03-21 09:55:15 -07001084
1085 // Routing?
1086 mOutputRoutes.decRouteActivity(session);
1087
Eric Laurente552edb2014-03-10 17:42:56 -07001088 // store time at which the stream was stopped - see isStreamActive()
1089 if (outputDesc->mRefCount[stream] == 0) {
Eric Laurentc722f302014-12-10 11:21:49 -08001090 // Automatically disable the remote submix input when output is stopped on a
1091 // re routing mix of type MIX_TYPE_RECORDERS
1092 if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1093 outputDesc->mPolicyMix != NULL &&
1094 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001095 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001096 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001097 outputDesc->mPolicyMix->mRegistrationId,
1098 "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001099 }
1100
Eric Laurente552edb2014-03-10 17:42:56 -07001101 outputDesc->mStopTime[stream] = systemTime();
Eric Laurent1c333e22014-05-20 10:48:17 -07001102 audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
Eric Laurente552edb2014-03-10 17:42:56 -07001103 // delay the device switch by twice the latency because stopOutput() is executed when
1104 // the track stop() command is received and at that time the audio track buffer can
1105 // still contain data that needs to be drained. The latency only covers the audio HAL
1106 // and kernel buffers. Also the latency does not always include additional delay in the
1107 // audio path (audio DSP, CODEC ...)
1108 setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
1109
1110 // force restoring the device selection on other active outputs if it differs from the
1111 // one being selected for this output
1112 for (size_t i = 0; i < mOutputs.size(); i++) {
1113 audio_io_handle_t curOutput = mOutputs.keyAt(i);
Eric Laurent1f2f2232014-06-02 12:01:23 -07001114 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001115 if (curOutput != output &&
1116 desc->isActive() &&
1117 outputDesc->sharesHwModuleWith(desc) &&
1118 (newDevice != desc->device())) {
1119 setOutputDevice(curOutput,
Eric Laurent1c333e22014-05-20 10:48:17 -07001120 getNewOutputDevice(curOutput, false /*fromCache*/),
Eric Laurente552edb2014-03-10 17:42:56 -07001121 true,
1122 outputDesc->mLatency*2);
1123 }
1124 }
1125 // update the outputs if stopping one with a stream that can affect notification routing
1126 handleNotificationRoutingForStream(stream);
1127 }
1128 return NO_ERROR;
1129 } else {
1130 ALOGW("stopOutput() refcount is already 0 for output %d", output);
1131 return INVALID_OPERATION;
1132 }
1133}
1134
Eric Laurente83b55d2014-11-14 10:06:21 -08001135void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
Eric Laurentcaf7f482014-11-25 17:50:47 -08001136 audio_stream_type_t stream __unused,
1137 audio_session_t session __unused)
Eric Laurente552edb2014-03-10 17:42:56 -07001138{
1139 ALOGV("releaseOutput() %d", output);
1140 ssize_t index = mOutputs.indexOfKey(output);
1141 if (index < 0) {
1142 ALOGW("releaseOutput() releasing unknown output %d", output);
1143 return;
1144 }
1145
1146#ifdef AUDIO_POLICY_TEST
1147 int testIndex = testOutputIndex(output);
1148 if (testIndex != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001149 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001150 if (outputDesc->isActive()) {
1151 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01001152 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07001153 mTestOutputs[testIndex] = 0;
1154 }
1155 return;
1156 }
1157#endif //AUDIO_POLICY_TEST
1158
Paul McLeanaa981192015-03-21 09:55:15 -07001159 // Routing
1160 mOutputRoutes.removeRoute(session);
1161
Eric Laurent1f2f2232014-06-02 12:01:23 -07001162 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index);
Eric Laurent3b73df72014-03-11 09:06:29 -07001163 if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
Eric Laurente552edb2014-03-10 17:42:56 -07001164 if (desc->mDirectOpenCount <= 0) {
1165 ALOGW("releaseOutput() invalid open count %d for output %d",
1166 desc->mDirectOpenCount, output);
1167 return;
1168 }
1169 if (--desc->mDirectOpenCount == 0) {
1170 closeOutput(output);
1171 // If effects where present on the output, audioflinger moved them to the primary
1172 // output by default: move them back to the appropriate output.
1173 audio_io_handle_t dstOutput = getOutputForEffect();
1174 if (dstOutput != mPrimaryOutput) {
1175 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
1176 }
Eric Laurentb52c1522014-05-20 11:27:36 -07001177 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001178 }
1179 }
1180}
1181
1182
Eric Laurentcaf7f482014-11-25 17:50:47 -08001183status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1184 audio_io_handle_t *input,
1185 audio_session_t session,
1186 uint32_t samplingRate,
1187 audio_format_t format,
1188 audio_channel_mask_t channelMask,
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001189 audio_input_flags_t flags,
1190 input_type_t *inputType)
Eric Laurente552edb2014-03-10 17:42:56 -07001191{
Eric Laurentcaf7f482014-11-25 17:50:47 -08001192 ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
1193 "session %d, flags %#x",
1194 attr->source, samplingRate, format, channelMask, session, flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001195
Eric Laurentcaf7f482014-11-25 17:50:47 -08001196 *input = AUDIO_IO_HANDLE_NONE;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001197 *inputType = API_INPUT_INVALID;
Eric Laurent275e8e92014-11-30 15:14:47 -08001198 audio_devices_t device;
1199 // handle legacy remote submix case where the address was not always specified
1200 String8 address = String8("");
Eric Laurent5dbe4712014-09-19 19:04:57 -07001201 bool isSoundTrigger = false;
Eric Laurentc447ded2015-01-06 08:47:05 -08001202 audio_source_t inputSource = attr->source;
1203 audio_source_t halInputSource;
Eric Laurentc722f302014-12-10 11:21:49 -08001204 AudioMix *policyMix = NULL;
Eric Laurent275e8e92014-11-30 15:14:47 -08001205
Eric Laurentc447ded2015-01-06 08:47:05 -08001206 if (inputSource == AUDIO_SOURCE_DEFAULT) {
1207 inputSource = AUDIO_SOURCE_MIC;
1208 }
1209 halInputSource = inputSource;
1210
1211 if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
Eric Laurent275e8e92014-11-30 15:14:47 -08001212 strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
François Gaffie036e1e92015-03-19 10:16:24 +01001213 status_t ret = mPolicyMixes.getInputMixForAttr(*attr, policyMix);
1214 if (ret != NO_ERROR) {
1215 return ret;
1216 }
1217 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
Eric Laurent275e8e92014-11-30 15:14:47 -08001218 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1219 address = String8(attr->tags + strlen("addr="));
Eric Laurent275e8e92014-11-30 15:14:47 -08001220 } else {
Eric Laurentc447ded2015-01-06 08:47:05 -08001221 device = getDeviceAndMixForInputSource(inputSource, &policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08001222 if (device == AUDIO_DEVICE_NONE) {
Eric Laurentc447ded2015-01-06 08:47:05 -08001223 ALOGW("getInputForAttr() could not find device for source %d", inputSource);
Eric Laurent275e8e92014-11-30 15:14:47 -08001224 return BAD_VALUE;
1225 }
Eric Laurentc722f302014-12-10 11:21:49 -08001226 if (policyMix != NULL) {
1227 address = policyMix->mRegistrationId;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001228 if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
1229 // there is an external policy, but this input is attached to a mix of recorders,
1230 // meaning it receives audio injected into the framework, so the recorder doesn't
1231 // know about it and is therefore considered "legacy"
1232 *inputType = API_INPUT_LEGACY;
1233 } else {
1234 // recording a mix of players defined by an external policy, we're rerouting for
1235 // an external policy
1236 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1237 }
Eric Laurentc722f302014-12-10 11:21:49 -08001238 } else if (audio_is_remote_submix_device(device)) {
1239 address = String8("0");
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001240 *inputType = API_INPUT_MIX_CAPTURE;
1241 } else {
1242 *inputType = API_INPUT_LEGACY;
Eric Laurentc722f302014-12-10 11:21:49 -08001243 }
Eric Laurent275e8e92014-11-30 15:14:47 -08001244 // adapt channel selection to input source
Eric Laurentc447ded2015-01-06 08:47:05 -08001245 switch (inputSource) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001246 case AUDIO_SOURCE_VOICE_UPLINK:
1247 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
1248 break;
1249 case AUDIO_SOURCE_VOICE_DOWNLINK:
1250 channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
1251 break;
1252 case AUDIO_SOURCE_VOICE_CALL:
1253 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
1254 break;
1255 default:
1256 break;
1257 }
Eric Laurentc447ded2015-01-06 08:47:05 -08001258 if (inputSource == AUDIO_SOURCE_HOTWORD) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001259 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1260 if (index >= 0) {
1261 *input = mSoundTriggerSessions.valueFor(session);
1262 isSoundTrigger = true;
1263 flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1264 ALOGV("SoundTrigger capture on session %d input %d", session, *input);
1265 } else {
1266 halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
1267 }
Eric Laurent5dbe4712014-09-19 19:04:57 -07001268 }
1269 }
1270
Eric Laurent275e8e92014-11-30 15:14:47 -08001271 sp<IOProfile> profile = getInputProfile(device, address,
1272 samplingRate, format, channelMask,
1273 flags);
Eric Laurent1c333e22014-05-20 10:48:17 -07001274 if (profile == 0) {
Eric Laurent5dbe4712014-09-19 19:04:57 -07001275 //retry without flags
1276 audio_input_flags_t log_flags = flags;
1277 flags = AUDIO_INPUT_FLAG_NONE;
Eric Laurent275e8e92014-11-30 15:14:47 -08001278 profile = getInputProfile(device, address,
1279 samplingRate, format, channelMask,
1280 flags);
Eric Laurent5dbe4712014-09-19 19:04:57 -07001281 if (profile == 0) {
Eric Laurentcaf7f482014-11-25 17:50:47 -08001282 ALOGW("getInputForAttr() could not find profile for device 0x%X, samplingRate %u,"
1283 "format %#x, channelMask 0x%X, flags %#x",
Eric Laurent5dbe4712014-09-19 19:04:57 -07001284 device, samplingRate, format, channelMask, log_flags);
Eric Laurentcaf7f482014-11-25 17:50:47 -08001285 return BAD_VALUE;
Eric Laurent5dbe4712014-09-19 19:04:57 -07001286 }
Eric Laurente552edb2014-03-10 17:42:56 -07001287 }
1288
1289 if (profile->mModule->mHandle == 0) {
Eric Laurentcaf7f482014-11-25 17:50:47 -08001290 ALOGE("getInputForAttr(): HW module %s not opened", profile->mModule->mName);
1291 return NO_INIT;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001292 }
1293
1294 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1295 config.sample_rate = samplingRate;
1296 config.channel_mask = channelMask;
1297 config.format = format;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001298
Eric Laurentcf2c0212014-07-25 16:20:43 -07001299 status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
Eric Laurentcaf7f482014-11-25 17:50:47 -08001300 input,
Eric Laurentcf2c0212014-07-25 16:20:43 -07001301 &config,
1302 &device,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07001303 address,
Eric Laurent1c9c2cc2014-08-28 19:37:25 -07001304 halInputSource,
Eric Laurentcf2c0212014-07-25 16:20:43 -07001305 flags);
1306
1307 // only accept input with the exact requested set of parameters
Eric Laurentcaf7f482014-11-25 17:50:47 -08001308 if (status != NO_ERROR || *input == AUDIO_IO_HANDLE_NONE ||
Eric Laurentcf2c0212014-07-25 16:20:43 -07001309 (samplingRate != config.sample_rate) ||
1310 (format != config.format) ||
1311 (channelMask != config.channel_mask)) {
Eric Laurentcaf7f482014-11-25 17:50:47 -08001312 ALOGW("getInputForAttr() failed opening input: samplingRate %d, format %d, channelMask %x",
Eric Laurentcf2c0212014-07-25 16:20:43 -07001313 samplingRate, format, channelMask);
Eric Laurentcaf7f482014-11-25 17:50:47 -08001314 if (*input != AUDIO_IO_HANDLE_NONE) {
1315 mpClientInterface->closeInput(*input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001316 }
Eric Laurentcaf7f482014-11-25 17:50:47 -08001317 return BAD_VALUE;
Eric Laurente552edb2014-03-10 17:42:56 -07001318 }
1319
Eric Laurent1f2f2232014-06-02 12:01:23 -07001320 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
Eric Laurentc447ded2015-01-06 08:47:05 -08001321 inputDesc->mInputSource = inputSource;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001322 inputDesc->mRefCount = 0;
1323 inputDesc->mOpenRefCount = 1;
Eric Laurente552edb2014-03-10 17:42:56 -07001324 inputDesc->mSamplingRate = samplingRate;
1325 inputDesc->mFormat = format;
1326 inputDesc->mChannelMask = channelMask;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001327 inputDesc->mDevice = device;
Eric Laurentc722f302014-12-10 11:21:49 -08001328 inputDesc->mSessions.add(session);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001329 inputDesc->mIsSoundTrigger = isSoundTrigger;
Eric Laurentc722f302014-12-10 11:21:49 -08001330 inputDesc->mPolicyMix = policyMix;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001331
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001332 ALOGV("getInputForAttr() returns input type = %d", inputType);
1333
Eric Laurentcaf7f482014-11-25 17:50:47 -08001334 addInput(*input, inputDesc);
Eric Laurentb52c1522014-05-20 11:27:36 -07001335 mpClientInterface->onAudioPortListUpdate();
Eric Laurentcaf7f482014-11-25 17:50:47 -08001336 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07001337}
1338
Eric Laurent4dc68062014-07-28 17:26:49 -07001339status_t AudioPolicyManager::startInput(audio_io_handle_t input,
1340 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001341{
1342 ALOGV("startInput() input %d", input);
1343 ssize_t index = mInputs.indexOfKey(input);
1344 if (index < 0) {
1345 ALOGW("startInput() unknown input %d", input);
1346 return BAD_VALUE;
1347 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001348 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001349
Eric Laurentc722f302014-12-10 11:21:49 -08001350 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001351 if (index < 0) {
1352 ALOGW("startInput() unknown session %d on input %d", session, input);
1353 return BAD_VALUE;
1354 }
1355
Glenn Kasten74a8e252014-07-24 14:09:55 -07001356 // virtual input devices are compatible with other input devices
François Gaffie53615e22015-03-19 09:24:12 +01001357 if (!is_virtual_input_device(inputDesc->mDevice)) {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001358
1359 // for a non-virtual input device, check if there is another (non-virtual) active input
François Gaffie53615e22015-03-19 09:24:12 +01001360 audio_io_handle_t activeInput = mInputs.getActiveInput();
Glenn Kasten74a8e252014-07-24 14:09:55 -07001361 if (activeInput != 0 && activeInput != input) {
1362
1363 // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1364 // otherwise the active input continues and the new input cannot be started.
Eric Laurent1f2f2232014-06-02 12:01:23 -07001365 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
Eric Laurente552edb2014-03-10 17:42:56 -07001366 if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001367 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
Eric Laurentc722f302014-12-10 11:21:49 -08001368 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
1369 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
Eric Laurente552edb2014-03-10 17:42:56 -07001370 } else {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001371 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
Eric Laurente552edb2014-03-10 17:42:56 -07001372 return INVALID_OPERATION;
1373 }
1374 }
1375 }
1376
Glenn Kasten74a8e252014-07-24 14:09:55 -07001377 if (inputDesc->mRefCount == 0) {
François Gaffie53615e22015-03-19 09:24:12 +01001378 if (mInputs.activeInputsCount() == 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001379 SoundTrigger::setCaptureState(true);
1380 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001381 setInputDevice(input, getNewInputDevice(input), true /* force */);
Eric Laurente552edb2014-03-10 17:42:56 -07001382
Eric Laurentc722f302014-12-10 11:21:49 -08001383 // automatically enable the remote submix output when input is started if not
1384 // used by a policy mix of type MIX_TYPE_RECORDERS
Glenn Kasten74a8e252014-07-24 14:09:55 -07001385 // For remote submix (a virtual device), we open only one input per capture request.
1386 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
Eric Laurentc722f302014-12-10 11:21:49 -08001387 String8 address = String8("");
1388 if (inputDesc->mPolicyMix == NULL) {
1389 address = String8("0");
1390 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1391 address = inputDesc->mPolicyMix->mRegistrationId;
1392 }
1393 if (address != "") {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001394 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001395 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001396 address, "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001397 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001398 }
Eric Laurente552edb2014-03-10 17:42:56 -07001399 }
1400
Eric Laurente552edb2014-03-10 17:42:56 -07001401 ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1402
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001403 inputDesc->mRefCount++;
Eric Laurente552edb2014-03-10 17:42:56 -07001404 return NO_ERROR;
1405}
1406
Eric Laurent4dc68062014-07-28 17:26:49 -07001407status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
1408 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001409{
1410 ALOGV("stopInput() input %d", input);
1411 ssize_t index = mInputs.indexOfKey(input);
1412 if (index < 0) {
1413 ALOGW("stopInput() unknown input %d", input);
1414 return BAD_VALUE;
1415 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001416 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001417
Eric Laurentc722f302014-12-10 11:21:49 -08001418 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001419 if (index < 0) {
1420 ALOGW("stopInput() unknown session %d on input %d", session, input);
1421 return BAD_VALUE;
1422 }
1423
Eric Laurente552edb2014-03-10 17:42:56 -07001424 if (inputDesc->mRefCount == 0) {
1425 ALOGW("stopInput() input %d already stopped", input);
1426 return INVALID_OPERATION;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001427 }
1428
1429 inputDesc->mRefCount--;
1430 if (inputDesc->mRefCount == 0) {
1431
Eric Laurentc722f302014-12-10 11:21:49 -08001432 // automatically disable the remote submix output when input is stopped if not
1433 // used by a policy mix of type MIX_TYPE_RECORDERS
Eric Laurente552edb2014-03-10 17:42:56 -07001434 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
Eric Laurentc722f302014-12-10 11:21:49 -08001435 String8 address = String8("");
1436 if (inputDesc->mPolicyMix == NULL) {
1437 address = String8("0");
1438 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1439 address = inputDesc->mPolicyMix->mRegistrationId;
1440 }
1441 if (address != "") {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001442 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001443 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001444 address, "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001445 }
Eric Laurente552edb2014-03-10 17:42:56 -07001446 }
1447
Eric Laurent1c333e22014-05-20 10:48:17 -07001448 resetInputDevice(input);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001449
François Gaffie53615e22015-03-19 09:24:12 +01001450 if (mInputs.activeInputsCount() == 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001451 SoundTrigger::setCaptureState(false);
1452 }
Eric Laurente552edb2014-03-10 17:42:56 -07001453 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001454 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07001455}
1456
Eric Laurent4dc68062014-07-28 17:26:49 -07001457void AudioPolicyManager::releaseInput(audio_io_handle_t input,
1458 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001459{
1460 ALOGV("releaseInput() %d", input);
1461 ssize_t index = mInputs.indexOfKey(input);
1462 if (index < 0) {
1463 ALOGW("releaseInput() releasing unknown input %d", input);
1464 return;
1465 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001466 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1467 ALOG_ASSERT(inputDesc != 0);
Eric Laurent4dc68062014-07-28 17:26:49 -07001468
Eric Laurentc722f302014-12-10 11:21:49 -08001469 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001470 if (index < 0) {
1471 ALOGW("releaseInput() unknown session %d on input %d", session, input);
1472 return;
1473 }
Eric Laurentc722f302014-12-10 11:21:49 -08001474 inputDesc->mSessions.remove(session);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001475 if (inputDesc->mOpenRefCount == 0) {
1476 ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
1477 return;
1478 }
1479 inputDesc->mOpenRefCount--;
1480 if (inputDesc->mOpenRefCount > 0) {
1481 ALOGV("releaseInput() exit > 0");
1482 return;
1483 }
1484
Eric Laurent05b90f82014-08-27 15:32:29 -07001485 closeInput(input);
Eric Laurentb52c1522014-05-20 11:27:36 -07001486 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001487 ALOGV("releaseInput() exit");
1488}
1489
Eric Laurentd4692962014-05-05 18:13:44 -07001490void AudioPolicyManager::closeAllInputs() {
Eric Laurent05b90f82014-08-27 15:32:29 -07001491 bool patchRemoved = false;
1492
Eric Laurentd4692962014-05-05 18:13:44 -07001493 for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
Eric Laurent05b90f82014-08-27 15:32:29 -07001494 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
1495 ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
1496 if (patch_index >= 0) {
1497 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
1498 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
1499 mAudioPatches.removeItemsAt(patch_index);
1500 patchRemoved = true;
1501 }
Eric Laurentd4692962014-05-05 18:13:44 -07001502 mpClientInterface->closeInput(mInputs.keyAt(input_index));
1503 }
1504 mInputs.clear();
Eric Laurent6a94d692014-05-20 11:18:06 -07001505 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07001506
1507 if (patchRemoved) {
1508 mpClientInterface->onAudioPatchListUpdate();
1509 }
Eric Laurentd4692962014-05-05 18:13:44 -07001510}
1511
Eric Laurente0720872014-03-11 09:30:41 -07001512void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001513 int indexMin,
1514 int indexMax)
1515{
1516 ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
François Gaffie2110e042015-03-24 08:41:51 +01001517 mEngine->initStreamVolume(stream, indexMin, indexMax);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001518 //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
1519 if (stream == AUDIO_STREAM_MUSIC) {
François Gaffie2110e042015-03-24 08:41:51 +01001520 mEngine->initStreamVolume(AUDIO_STREAM_ACCESSIBILITY, indexMin, indexMax);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001521 }
Eric Laurente552edb2014-03-10 17:42:56 -07001522}
1523
Eric Laurente0720872014-03-11 09:30:41 -07001524status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01001525 int index,
1526 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07001527{
1528
François Gaffiedfd74092015-03-19 12:10:59 +01001529 if ((index < mStreams[stream].getVolumeIndexMin()) ||
1530 (index > mStreams[stream].getVolumeIndexMax())) {
Eric Laurente552edb2014-03-10 17:42:56 -07001531 return BAD_VALUE;
1532 }
1533 if (!audio_is_output_device(device)) {
1534 return BAD_VALUE;
1535 }
1536
1537 // Force max volume if stream cannot be muted
François Gaffiedfd74092015-03-19 12:10:59 +01001538 if (!mStreams.canBeMuted(stream)) index = mStreams[stream].getVolumeIndexMax();
Eric Laurente552edb2014-03-10 17:42:56 -07001539
1540 ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1541 stream, device, index);
1542
1543 // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1544 // clear all device specific values
1545 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
François Gaffiedfd74092015-03-19 12:10:59 +01001546 mStreams.clearCurrentVolumeIndex(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07001547 }
François Gaffiedfd74092015-03-19 12:10:59 +01001548 mStreams.addCurrentVolumeIndex(stream, device, index);
Eric Laurente552edb2014-03-10 17:42:56 -07001549
Eric Laurent31551f82014-10-10 18:21:56 -07001550 // update volume on all outputs whose current device is also selected by the same
1551 // strategy as the device specified by the caller
1552 audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001553
1554
1555 //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
1556 audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE;
1557 if (stream == AUDIO_STREAM_MUSIC) {
François Gaffiedfd74092015-03-19 12:10:59 +01001558 mStreams.addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001559 accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/);
1560 }
1561 if ((device != AUDIO_DEVICE_OUT_DEFAULT) &&
1562 (device & (strategyDevice | accessibilityDevice)) == 0) {
Eric Laurent31551f82014-10-10 18:21:56 -07001563 return NO_ERROR;
1564 }
Eric Laurente552edb2014-03-10 17:42:56 -07001565 status_t status = NO_ERROR;
1566 for (size_t i = 0; i < mOutputs.size(); i++) {
François Gaffiedfd74092015-03-19 12:10:59 +01001567 audio_devices_t curDevice = Volume::getDeviceForVolume(mOutputs.valueAt(i)->device());
Eric Laurent31551f82014-10-10 18:21:56 -07001568 if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {
Eric Laurente552edb2014-03-10 17:42:56 -07001569 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1570 if (volStatus != NO_ERROR) {
1571 status = volStatus;
1572 }
1573 }
Eric Laurent223fd5c2014-11-11 13:43:36 -08001574 if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)) {
1575 status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY,
1576 index, mOutputs.keyAt(i), curDevice);
1577 }
Eric Laurente552edb2014-03-10 17:42:56 -07001578 }
1579 return status;
1580}
1581
Eric Laurente0720872014-03-11 09:30:41 -07001582status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001583 int *index,
1584 audio_devices_t device)
1585{
1586 if (index == NULL) {
1587 return BAD_VALUE;
1588 }
1589 if (!audio_is_output_device(device)) {
1590 return BAD_VALUE;
1591 }
1592 // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
1593 // the strategy the stream belongs to.
1594 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1595 device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1596 }
François Gaffiedfd74092015-03-19 12:10:59 +01001597 device = Volume::getDeviceForVolume(device);
Eric Laurente552edb2014-03-10 17:42:56 -07001598
1599 *index = mStreams[stream].getVolumeIndex(device);
1600 ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1601 return NO_ERROR;
1602}
1603
Eric Laurente0720872014-03-11 09:30:41 -07001604audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
Eric Laurente552edb2014-03-10 17:42:56 -07001605 const SortedVector<audio_io_handle_t>& outputs)
1606{
1607 // select one output among several suitable for global effects.
1608 // The priority is as follows:
1609 // 1: An offloaded output. If the effect ends up not being offloadable,
1610 // AudioFlinger will invalidate the track and the offloaded output
1611 // will be closed causing the effect to be moved to a PCM output.
1612 // 2: A deep buffer output
1613 // 3: the first output in the list
1614
1615 if (outputs.size() == 0) {
1616 return 0;
1617 }
1618
1619 audio_io_handle_t outputOffloaded = 0;
1620 audio_io_handle_t outputDeepBuffer = 0;
1621
1622 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001623 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurentd4692962014-05-05 18:13:44 -07001624 ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -07001625 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1626 outputOffloaded = outputs[i];
1627 }
1628 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1629 outputDeepBuffer = outputs[i];
1630 }
1631 }
1632
1633 ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
1634 outputOffloaded, outputDeepBuffer);
1635 if (outputOffloaded != 0) {
1636 return outputOffloaded;
1637 }
1638 if (outputDeepBuffer != 0) {
1639 return outputDeepBuffer;
1640 }
1641
1642 return outputs[0];
1643}
1644
Eric Laurente0720872014-03-11 09:30:41 -07001645audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
Eric Laurente552edb2014-03-10 17:42:56 -07001646{
1647 // apply simple rule where global effects are attached to the same output as MUSIC streams
1648
Eric Laurent3b73df72014-03-11 09:06:29 -07001649 routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
Eric Laurente552edb2014-03-10 17:42:56 -07001650 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
1651 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
1652
1653 audio_io_handle_t output = selectOutputForEffects(dstOutputs);
1654 ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
1655 output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags);
1656
1657 return output;
1658}
1659
Eric Laurente0720872014-03-11 09:30:41 -07001660status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
Eric Laurente552edb2014-03-10 17:42:56 -07001661 audio_io_handle_t io,
1662 uint32_t strategy,
1663 int session,
1664 int id)
1665{
1666 ssize_t index = mOutputs.indexOfKey(io);
1667 if (index < 0) {
1668 index = mInputs.indexOfKey(io);
1669 if (index < 0) {
1670 ALOGW("registerEffect() unknown io %d", io);
1671 return INVALID_OPERATION;
1672 }
1673 }
François Gaffie45ed3b02015-03-19 10:35:14 +01001674 return mEffects.registerEffect(desc, io, strategy, session, id);
Eric Laurente552edb2014-03-10 17:42:56 -07001675}
1676
Eric Laurente0720872014-03-11 09:30:41 -07001677bool AudioPolicyManager::isSourceActive(audio_source_t source) const
Eric Laurente552edb2014-03-10 17:42:56 -07001678{
1679 for (size_t i = 0; i < mInputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001680 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
Eric Laurenta34c9ce2014-12-19 11:16:32 -08001681 if (inputDescriptor->mRefCount == 0) {
1682 continue;
1683 }
1684 if (inputDescriptor->mInputSource == (int)source) {
Eric Laurente552edb2014-03-10 17:42:56 -07001685 return true;
1686 }
Eric Laurenta34c9ce2014-12-19 11:16:32 -08001687 // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
1688 // corresponds to an active capture triggered by a hardware hotword recognition
1689 if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
1690 (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) {
1691 // FIXME: we should not assume that the first session is the active one and keep
1692 // activity count per session. Same in startInput().
1693 ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0));
1694 if (index >= 0) {
1695 return true;
1696 }
1697 }
Eric Laurente552edb2014-03-10 17:42:56 -07001698 }
1699 return false;
1700}
1701
Eric Laurent275e8e92014-11-30 15:14:47 -08001702// Register a list of custom mixes with their attributes and format.
1703// When a mix is registered, corresponding input and output profiles are
1704// added to the remote submix hw module. The profile contains only the
1705// parameters (sampling rate, format...) specified by the mix.
1706// The corresponding input remote submix device is also connected.
1707//
1708// When a remote submix device is connected, the address is checked to select the
1709// appropriate profile and the corresponding input or output stream is opened.
1710//
1711// When capture starts, getInputForAttr() will:
1712// - 1 look for a mix matching the address passed in attribtutes tags if any
1713// - 2 if none found, getDeviceForInputSource() will:
1714// - 2.1 look for a mix matching the attributes source
1715// - 2.2 if none found, default to device selection by policy rules
1716// At this time, the corresponding output remote submix device is also connected
1717// and active playback use cases can be transferred to this mix if needed when reconnecting
1718// after AudioTracks are invalidated
1719//
1720// When playback starts, getOutputForAttr() will:
1721// - 1 look for a mix matching the address passed in attribtutes tags if any
1722// - 2 if none found, look for a mix matching the attributes usage
1723// - 3 if none found, default to device and output selection by policy rules.
1724
1725status_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes)
1726{
1727 sp<HwModule> module;
1728 for (size_t i = 0; i < mHwModules.size(); i++) {
1729 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 &&
1730 mHwModules[i]->mHandle != 0) {
1731 module = mHwModules[i];
1732 break;
1733 }
1734 }
1735
1736 if (module == 0) {
1737 return INVALID_OPERATION;
1738 }
1739
1740 ALOGV("registerPolicyMixes() num mixes %d", mixes.size());
1741
1742 for (size_t i = 0; i < mixes.size(); i++) {
1743 String8 address = mixes[i].mRegistrationId;
François Gaffie036e1e92015-03-19 10:16:24 +01001744
1745 if (mPolicyMixes.registerMix(address, mixes[i]) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001746 continue;
1747 }
1748 audio_config_t outputConfig = mixes[i].mFormat;
1749 audio_config_t inputConfig = mixes[i].mFormat;
1750 // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
1751 // stereo and let audio flinger do the channel conversion if needed.
1752 outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1753 inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
1754 module->addOutputProfile(address, &outputConfig,
1755 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
1756 module->addInputProfile(address, &inputConfig,
1757 AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
François Gaffie036e1e92015-03-19 10:16:24 +01001758
Eric Laurentc722f302014-12-10 11:21:49 -08001759 if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001760 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001761 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001762 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001763 } else {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001764 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001765 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001766 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001767 }
Eric Laurent275e8e92014-11-30 15:14:47 -08001768 }
1769 return NO_ERROR;
1770}
1771
1772status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
1773{
1774 sp<HwModule> module;
1775 for (size_t i = 0; i < mHwModules.size(); i++) {
1776 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 &&
1777 mHwModules[i]->mHandle != 0) {
1778 module = mHwModules[i];
1779 break;
1780 }
1781 }
1782
1783 if (module == 0) {
1784 return INVALID_OPERATION;
1785 }
1786
1787 ALOGV("unregisterPolicyMixes() num mixes %d", mixes.size());
1788
1789 for (size_t i = 0; i < mixes.size(); i++) {
1790 String8 address = mixes[i].mRegistrationId;
François Gaffie036e1e92015-03-19 10:16:24 +01001791
1792 if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001793 continue;
1794 }
1795
Eric Laurentc722f302014-12-10 11:21:49 -08001796 if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
1797 AUDIO_POLICY_DEVICE_STATE_AVAILABLE)
1798 {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001799 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001800 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001801 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001802 }
Eric Laurent275e8e92014-11-30 15:14:47 -08001803
1804 if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
1805 AUDIO_POLICY_DEVICE_STATE_AVAILABLE)
1806 {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001807 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurent275e8e92014-11-30 15:14:47 -08001808 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001809 address.string(), "remote-submix");
Eric Laurent275e8e92014-11-30 15:14:47 -08001810 }
1811 module->removeOutputProfile(address);
1812 module->removeInputProfile(address);
1813 }
1814 return NO_ERROR;
1815}
1816
Eric Laurente552edb2014-03-10 17:42:56 -07001817
Eric Laurente0720872014-03-11 09:30:41 -07001818status_t AudioPolicyManager::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07001819{
1820 const size_t SIZE = 256;
1821 char buffer[SIZE];
1822 String8 result;
1823
1824 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1825 result.append(buffer);
1826
1827 snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
1828 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001829 snprintf(buffer, SIZE, " Phone state: %d\n", mEngine->getPhoneState());
Eric Laurente552edb2014-03-10 17:42:56 -07001830 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001831 snprintf(buffer, SIZE, " Force use for communications %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01001832 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
Eric Laurente552edb2014-03-10 17:42:56 -07001833 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001834 snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
Eric Laurente552edb2014-03-10 17:42:56 -07001835 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001836 snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
Eric Laurente552edb2014-03-10 17:42:56 -07001837 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001838 snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
Eric Laurente552edb2014-03-10 17:42:56 -07001839 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001840 snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
Eric Laurente552edb2014-03-10 17:42:56 -07001841 result.append(buffer);
Jungshik Jang7b24ee32014-07-15 19:38:42 +09001842 snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01001843 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
Jungshik Jang7b24ee32014-07-15 19:38:42 +09001844 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01001845 write(fd, result.string(), result.size());
Eric Laurente552edb2014-03-10 17:42:56 -07001846
François Gaffie53615e22015-03-19 09:24:12 +01001847 mAvailableOutputDevices.dump(fd, String8("output"));
1848 mAvailableInputDevices.dump(fd, String8("input"));
1849 mHwModules.dump(fd);
1850 mOutputs.dump(fd);
1851 mInputs.dump(fd);
François Gaffiedfd74092015-03-19 12:10:59 +01001852 mStreams.dump(fd);
François Gaffie45ed3b02015-03-19 10:35:14 +01001853 mEffects.dump(fd);
François Gaffie53615e22015-03-19 09:24:12 +01001854 mAudioPatches.dump(fd);
Eric Laurente552edb2014-03-10 17:42:56 -07001855
1856 return NO_ERROR;
1857}
1858
1859// This function checks for the parameters which can be offloaded.
1860// This can be enhanced depending on the capability of the DSP and policy
1861// of the system.
Eric Laurente0720872014-03-11 09:30:41 -07001862bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -07001863{
1864 ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
Eric Laurentd4692962014-05-05 18:13:44 -07001865 " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
Eric Laurente552edb2014-03-10 17:42:56 -07001866 offloadInfo.sample_rate, offloadInfo.channel_mask,
1867 offloadInfo.format,
1868 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
1869 offloadInfo.has_video);
1870
1871 // Check if offload has been disabled
1872 char propValue[PROPERTY_VALUE_MAX];
1873 if (property_get("audio.offload.disable", propValue, "0")) {
1874 if (atoi(propValue) != 0) {
1875 ALOGV("offload disabled by audio.offload.disable=%s", propValue );
1876 return false;
1877 }
1878 }
1879
1880 // Check if stream type is music, then only allow offload as of now.
1881 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
1882 {
1883 ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
1884 return false;
1885 }
1886
1887 //TODO: enable audio offloading with video when ready
1888 if (offloadInfo.has_video)
1889 {
1890 ALOGV("isOffloadSupported: has_video == true, returning false");
1891 return false;
1892 }
1893
1894 //If duration is less than minimum value defined in property, return false
1895 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1896 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1897 ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1898 return false;
1899 }
1900 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1901 ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
1902 return false;
1903 }
1904
1905 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1906 // creating an offloaded track and tearing it down immediately after start when audioflinger
1907 // detects there is an active non offloadable effect.
1908 // FIXME: We should check the audio session here but we do not have it in this context.
1909 // This may prevent offloading in rare situations where effects are left active by apps
1910 // in the background.
François Gaffie45ed3b02015-03-19 10:35:14 +01001911 if (mEffects.isNonOffloadableEffectEnabled()) {
Eric Laurente552edb2014-03-10 17:42:56 -07001912 return false;
1913 }
1914
1915 // See if there is a profile to support this.
1916 // AUDIO_DEVICE_NONE
Eric Laurent1c333e22014-05-20 10:48:17 -07001917 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Eric Laurente552edb2014-03-10 17:42:56 -07001918 offloadInfo.sample_rate,
1919 offloadInfo.format,
1920 offloadInfo.channel_mask,
1921 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Eric Laurent1c333e22014-05-20 10:48:17 -07001922 ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
1923 return (profile != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07001924}
1925
Eric Laurent6a94d692014-05-20 11:18:06 -07001926status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
1927 audio_port_type_t type,
1928 unsigned int *num_ports,
1929 struct audio_port *ports,
1930 unsigned int *generation)
1931{
1932 if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
1933 generation == NULL) {
1934 return BAD_VALUE;
1935 }
1936 ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
1937 if (ports == NULL) {
1938 *num_ports = 0;
1939 }
1940
1941 size_t portsWritten = 0;
1942 size_t portsMax = *num_ports;
1943 *num_ports = 0;
1944 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
1945 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
1946 for (size_t i = 0;
1947 i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
1948 mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
1949 }
1950 *num_ports += mAvailableOutputDevices.size();
1951 }
1952 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
1953 for (size_t i = 0;
1954 i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
1955 mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
1956 }
1957 *num_ports += mAvailableInputDevices.size();
1958 }
1959 }
1960 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
1961 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
1962 for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
1963 mInputs[i]->toAudioPort(&ports[portsWritten++]);
1964 }
1965 *num_ports += mInputs.size();
1966 }
1967 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent84c70242014-06-23 08:46:27 -07001968 size_t numOutputs = 0;
1969 for (size_t i = 0; i < mOutputs.size(); i++) {
1970 if (!mOutputs[i]->isDuplicated()) {
1971 numOutputs++;
1972 if (portsWritten < portsMax) {
1973 mOutputs[i]->toAudioPort(&ports[portsWritten++]);
1974 }
1975 }
Eric Laurent6a94d692014-05-20 11:18:06 -07001976 }
Eric Laurent84c70242014-06-23 08:46:27 -07001977 *num_ports += numOutputs;
Eric Laurent6a94d692014-05-20 11:18:06 -07001978 }
1979 }
1980 *generation = curAudioPortGeneration();
Mark Salyzynbeb9e302014-06-18 16:33:15 -07001981 ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
Eric Laurent6a94d692014-05-20 11:18:06 -07001982 return NO_ERROR;
1983}
1984
1985status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
1986{
1987 return NO_ERROR;
1988}
1989
Eric Laurent6a94d692014-05-20 11:18:06 -07001990status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
1991 audio_patch_handle_t *handle,
1992 uid_t uid)
1993{
1994 ALOGV("createAudioPatch()");
1995
1996 if (handle == NULL || patch == NULL) {
1997 return BAD_VALUE;
1998 }
1999 ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
2000
Eric Laurent874c42872014-08-08 15:13:39 -07002001 if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2002 patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2003 return BAD_VALUE;
2004 }
2005 // only one source per audio patch supported for now
2006 if (patch->num_sources > 1) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002007 return INVALID_OPERATION;
2008 }
Eric Laurent874c42872014-08-08 15:13:39 -07002009
2010 if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002011 return INVALID_OPERATION;
2012 }
Eric Laurent874c42872014-08-08 15:13:39 -07002013 for (size_t i = 0; i < patch->num_sinks; i++) {
2014 if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2015 return INVALID_OPERATION;
2016 }
2017 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002018
2019 sp<AudioPatch> patchDesc;
2020 ssize_t index = mAudioPatches.indexOfKey(*handle);
2021
Eric Laurent6a94d692014-05-20 11:18:06 -07002022 ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
2023 patch->sources[0].role,
2024 patch->sources[0].type);
Eric Laurent874c42872014-08-08 15:13:39 -07002025#if LOG_NDEBUG == 0
2026 for (size_t i = 0; i < patch->num_sinks; i++) {
2027 ALOGV("createAudioPatch sink %d: id %d role %d type %d", i, patch->sinks[i].id,
2028 patch->sinks[i].role,
2029 patch->sinks[i].type);
2030 }
2031#endif
Eric Laurent6a94d692014-05-20 11:18:06 -07002032
2033 if (index >= 0) {
2034 patchDesc = mAudioPatches.valueAt(index);
2035 ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2036 mUidCached, patchDesc->mUid, uid);
2037 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2038 return INVALID_OPERATION;
2039 }
2040 } else {
2041 *handle = 0;
2042 }
2043
2044 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
François Gaffie53615e22015-03-19 09:24:12 +01002045 sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002046 if (outputDesc == NULL) {
2047 ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
2048 return BAD_VALUE;
2049 }
Eric Laurent84c70242014-06-23 08:46:27 -07002050 ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
2051 outputDesc->mIoHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002052 if (patchDesc != 0) {
2053 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
2054 ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
2055 patchDesc->mPatch.sources[0].id, patch->sources[0].id);
2056 return BAD_VALUE;
2057 }
2058 }
Eric Laurent874c42872014-08-08 15:13:39 -07002059 DeviceVector devices;
2060 for (size_t i = 0; i < patch->num_sinks; i++) {
2061 // Only support mix to devices connection
2062 // TODO add support for mix to mix connection
2063 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2064 ALOGV("createAudioPatch() source mix but sink is not a device");
2065 return INVALID_OPERATION;
2066 }
2067 sp<DeviceDescriptor> devDesc =
2068 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2069 if (devDesc == 0) {
2070 ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2071 return BAD_VALUE;
2072 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002073
François Gaffie53615e22015-03-19 09:24:12 +01002074 if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002075 devDesc->mAddress,
Eric Laurent874c42872014-08-08 15:13:39 -07002076 patch->sources[0].sample_rate,
François Gaffie53615e22015-03-19 09:24:12 +01002077 NULL, // updatedSamplingRate
2078 patch->sources[0].format,
2079 patch->sources[0].channel_mask,
2080 AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
2081 ALOGV("createAudioPatch() profile not supported for device %08x", devDesc->type());
Eric Laurent874c42872014-08-08 15:13:39 -07002082 return INVALID_OPERATION;
2083 }
2084 devices.add(devDesc);
2085 }
2086 if (devices.size() == 0) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002087 return INVALID_OPERATION;
2088 }
Eric Laurent874c42872014-08-08 15:13:39 -07002089
Eric Laurent6a94d692014-05-20 11:18:06 -07002090 // TODO: reconfigure output format and channels here
2091 ALOGV("createAudioPatch() setting device %08x on output %d",
Eric Laurent874c42872014-08-08 15:13:39 -07002092 devices.types(), outputDesc->mIoHandle);
2093 setOutputDevice(outputDesc->mIoHandle, devices.types(), true, 0, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002094 index = mAudioPatches.indexOfKey(*handle);
2095 if (index >= 0) {
2096 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2097 ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
2098 }
2099 patchDesc = mAudioPatches.valueAt(index);
2100 patchDesc->mUid = uid;
2101 ALOGV("createAudioPatch() success");
2102 } else {
2103 ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
2104 return INVALID_OPERATION;
2105 }
2106 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2107 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
2108 // input device to input mix connection
Eric Laurent874c42872014-08-08 15:13:39 -07002109 // only one sink supported when connecting an input device to a mix
2110 if (patch->num_sinks > 1) {
2111 return INVALID_OPERATION;
2112 }
François Gaffie53615e22015-03-19 09:24:12 +01002113 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002114 if (inputDesc == NULL) {
2115 return BAD_VALUE;
2116 }
2117 if (patchDesc != 0) {
2118 if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
2119 return BAD_VALUE;
2120 }
2121 }
2122 sp<DeviceDescriptor> devDesc =
2123 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
2124 if (devDesc == 0) {
2125 return BAD_VALUE;
2126 }
2127
François Gaffie53615e22015-03-19 09:24:12 +01002128 if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002129 devDesc->mAddress,
2130 patch->sinks[0].sample_rate,
2131 NULL, /*updatedSampleRate*/
2132 patch->sinks[0].format,
2133 patch->sinks[0].channel_mask,
2134 // FIXME for the parameter type,
2135 // and the NONE
2136 (audio_output_flags_t)
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002137 AUDIO_INPUT_FLAG_NONE)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002138 return INVALID_OPERATION;
2139 }
2140 // TODO: reconfigure output format and channels here
2141 ALOGV("createAudioPatch() setting device %08x on output %d",
François Gaffie53615e22015-03-19 09:24:12 +01002142 devDesc->type(), inputDesc->mIoHandle);
2143 setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002144 index = mAudioPatches.indexOfKey(*handle);
2145 if (index >= 0) {
2146 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2147 ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
2148 }
2149 patchDesc = mAudioPatches.valueAt(index);
2150 patchDesc->mUid = uid;
2151 ALOGV("createAudioPatch() success");
2152 } else {
2153 ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
2154 return INVALID_OPERATION;
2155 }
2156 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2157 // device to device connection
2158 if (patchDesc != 0) {
Eric Laurent874c42872014-08-08 15:13:39 -07002159 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002160 return BAD_VALUE;
2161 }
2162 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002163 sp<DeviceDescriptor> srcDeviceDesc =
2164 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
Eric Laurent58f8eb72014-09-12 16:19:41 -07002165 if (srcDeviceDesc == 0) {
2166 return BAD_VALUE;
2167 }
Eric Laurent874c42872014-08-08 15:13:39 -07002168
Eric Laurent6a94d692014-05-20 11:18:06 -07002169 //update source and sink with our own data as the data passed in the patch may
2170 // be incomplete.
2171 struct audio_patch newPatch = *patch;
2172 srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
Eric Laurent6a94d692014-05-20 11:18:06 -07002173
Eric Laurent874c42872014-08-08 15:13:39 -07002174 for (size_t i = 0; i < patch->num_sinks; i++) {
2175 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2176 ALOGV("createAudioPatch() source device but one sink is not a device");
2177 return INVALID_OPERATION;
2178 }
2179
2180 sp<DeviceDescriptor> sinkDeviceDesc =
2181 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2182 if (sinkDeviceDesc == 0) {
2183 return BAD_VALUE;
2184 }
2185 sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
2186
2187 if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) {
2188 // only one sink supported when connected devices across HW modules
2189 if (patch->num_sinks > 1) {
Eric Laurent83b88082014-06-20 18:31:16 -07002190 return INVALID_OPERATION;
2191 }
Eric Laurent874c42872014-08-08 15:13:39 -07002192 SortedVector<audio_io_handle_t> outputs =
François Gaffie53615e22015-03-19 09:24:12 +01002193 getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
Eric Laurent874c42872014-08-08 15:13:39 -07002194 // if the sink device is reachable via an opened output stream, request to go via
2195 // this output stream by adding a second source to the patch description
Eric Laurent8838a382014-09-08 16:44:28 -07002196 audio_io_handle_t output = selectOutput(outputs,
2197 AUDIO_OUTPUT_FLAG_NONE,
2198 AUDIO_FORMAT_INVALID);
Eric Laurent874c42872014-08-08 15:13:39 -07002199 if (output != AUDIO_IO_HANDLE_NONE) {
2200 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2201 if (outputDesc->isDuplicated()) {
2202 return INVALID_OPERATION;
2203 }
2204 outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
2205 newPatch.num_sources = 2;
2206 }
Eric Laurent83b88082014-06-20 18:31:16 -07002207 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002208 }
2209 // TODO: check from routing capabilities in config file and other conflicting patches
2210
2211 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
2212 if (index >= 0) {
2213 afPatchHandle = patchDesc->mAfPatchHandle;
2214 }
2215
2216 status_t status = mpClientInterface->createAudioPatch(&newPatch,
2217 &afPatchHandle,
2218 0);
2219 ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
2220 status, afPatchHandle);
2221 if (status == NO_ERROR) {
2222 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01002223 patchDesc = new AudioPatch(&newPatch, uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07002224 addAudioPatch(patchDesc->mHandle, patchDesc);
2225 } else {
2226 patchDesc->mPatch = newPatch;
2227 }
2228 patchDesc->mAfPatchHandle = afPatchHandle;
2229 *handle = patchDesc->mHandle;
2230 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002231 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002232 } else {
2233 ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
2234 status);
2235 return INVALID_OPERATION;
2236 }
2237 } else {
2238 return BAD_VALUE;
2239 }
2240 } else {
2241 return BAD_VALUE;
2242 }
2243 return NO_ERROR;
2244}
2245
2246status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
2247 uid_t uid)
2248{
2249 ALOGV("releaseAudioPatch() patch %d", handle);
2250
2251 ssize_t index = mAudioPatches.indexOfKey(handle);
2252
2253 if (index < 0) {
2254 return BAD_VALUE;
2255 }
2256 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
2257 ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2258 mUidCached, patchDesc->mUid, uid);
2259 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2260 return INVALID_OPERATION;
2261 }
2262
2263 struct audio_patch *patch = &patchDesc->mPatch;
2264 patchDesc->mUid = mUidCached;
2265 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
François Gaffie53615e22015-03-19 09:24:12 +01002266 sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002267 if (outputDesc == NULL) {
2268 ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
2269 return BAD_VALUE;
2270 }
2271
2272 setOutputDevice(outputDesc->mIoHandle,
2273 getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/),
2274 true,
2275 0,
2276 NULL);
2277 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2278 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
François Gaffie53615e22015-03-19 09:24:12 +01002279 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002280 if (inputDesc == NULL) {
2281 ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
2282 return BAD_VALUE;
2283 }
2284 setInputDevice(inputDesc->mIoHandle,
2285 getNewInputDevice(inputDesc->mIoHandle),
2286 true,
2287 NULL);
2288 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2289 audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle;
2290 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
2291 ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
2292 status, patchDesc->mAfPatchHandle);
2293 removeAudioPatch(patchDesc->mHandle);
2294 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002295 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002296 } else {
2297 return BAD_VALUE;
2298 }
2299 } else {
2300 return BAD_VALUE;
2301 }
2302 return NO_ERROR;
2303}
2304
2305status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
2306 struct audio_patch *patches,
2307 unsigned int *generation)
2308{
François Gaffie53615e22015-03-19 09:24:12 +01002309 if (generation == NULL) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002310 return BAD_VALUE;
2311 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002312 *generation = curAudioPortGeneration();
François Gaffie53615e22015-03-19 09:24:12 +01002313 return mAudioPatches.listAudioPatches(num_patches, patches);
Eric Laurent6a94d692014-05-20 11:18:06 -07002314}
2315
Eric Laurente1715a42014-05-20 11:30:42 -07002316status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
Eric Laurent6a94d692014-05-20 11:18:06 -07002317{
Eric Laurente1715a42014-05-20 11:30:42 -07002318 ALOGV("setAudioPortConfig()");
2319
2320 if (config == NULL) {
2321 return BAD_VALUE;
2322 }
2323 ALOGV("setAudioPortConfig() on port handle %d", config->id);
2324 // Only support gain configuration for now
Eric Laurenta121f902014-06-03 13:32:54 -07002325 if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
2326 return INVALID_OPERATION;
Eric Laurente1715a42014-05-20 11:30:42 -07002327 }
2328
Eric Laurenta121f902014-06-03 13:32:54 -07002329 sp<AudioPortConfig> audioPortConfig;
Eric Laurente1715a42014-05-20 11:30:42 -07002330 if (config->type == AUDIO_PORT_TYPE_MIX) {
2331 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
François Gaffie53615e22015-03-19 09:24:12 +01002332 sp<AudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002333 if (outputDesc == NULL) {
2334 return BAD_VALUE;
2335 }
Eric Laurent84c70242014-06-23 08:46:27 -07002336 ALOG_ASSERT(!outputDesc->isDuplicated(),
2337 "setAudioPortConfig() called on duplicated output %d",
2338 outputDesc->mIoHandle);
Eric Laurenta121f902014-06-03 13:32:54 -07002339 audioPortConfig = outputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002340 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
François Gaffie53615e22015-03-19 09:24:12 +01002341 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002342 if (inputDesc == NULL) {
2343 return BAD_VALUE;
2344 }
Eric Laurenta121f902014-06-03 13:32:54 -07002345 audioPortConfig = inputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002346 } else {
2347 return BAD_VALUE;
2348 }
2349 } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
2350 sp<DeviceDescriptor> deviceDesc;
2351 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
2352 deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
2353 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
2354 deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
2355 } else {
2356 return BAD_VALUE;
2357 }
2358 if (deviceDesc == NULL) {
2359 return BAD_VALUE;
2360 }
Eric Laurenta121f902014-06-03 13:32:54 -07002361 audioPortConfig = deviceDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002362 } else {
2363 return BAD_VALUE;
2364 }
2365
Eric Laurenta121f902014-06-03 13:32:54 -07002366 struct audio_port_config backupConfig;
2367 status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
2368 if (status == NO_ERROR) {
2369 struct audio_port_config newConfig;
2370 audioPortConfig->toAudioPortConfig(&newConfig, config);
2371 status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
Eric Laurente1715a42014-05-20 11:30:42 -07002372 }
Eric Laurenta121f902014-06-03 13:32:54 -07002373 if (status != NO_ERROR) {
2374 audioPortConfig->applyAudioPortConfig(&backupConfig);
Eric Laurente1715a42014-05-20 11:30:42 -07002375 }
Eric Laurente1715a42014-05-20 11:30:42 -07002376
2377 return status;
Eric Laurent6a94d692014-05-20 11:18:06 -07002378}
2379
2380void AudioPolicyManager::clearAudioPatches(uid_t uid)
2381{
Eric Laurent0add0fd2014-12-04 18:58:14 -08002382 for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002383 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
2384 if (patchDesc->mUid == uid) {
Eric Laurent0add0fd2014-12-04 18:58:14 -08002385 releaseAudioPatch(mAudioPatches.keyAt(i), uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07002386 }
2387 }
2388}
2389
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002390status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
2391 audio_io_handle_t *ioHandle,
2392 audio_devices_t *device)
2393{
2394 *session = (audio_session_t)mpClientInterface->newAudioUniqueId();
2395 *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId();
Eric Laurentc73ca6e2014-12-12 14:34:22 -08002396 *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002397
François Gaffiedf372692015-03-19 10:43:27 +01002398 return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002399}
2400
Eric Laurente552edb2014-03-10 17:42:56 -07002401// ----------------------------------------------------------------------------
Eric Laurente0720872014-03-11 09:30:41 -07002402// AudioPolicyManager
Eric Laurente552edb2014-03-10 17:42:56 -07002403// ----------------------------------------------------------------------------
Eric Laurent6a94d692014-05-20 11:18:06 -07002404uint32_t AudioPolicyManager::nextAudioPortGeneration()
2405{
2406 return android_atomic_inc(&mAudioPortGeneration);
2407}
2408
Eric Laurente0720872014-03-11 09:30:41 -07002409AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
Eric Laurente552edb2014-03-10 17:42:56 -07002410 :
2411#ifdef AUDIO_POLICY_TEST
2412 Thread(false),
2413#endif //AUDIO_POLICY_TEST
2414 mPrimaryOutput((audio_io_handle_t)0),
Eric Laurente552edb2014-03-10 17:42:56 -07002415 mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
Eric Laurent3a4311c2014-03-17 12:00:47 -07002416 mA2dpSuspended(false),
Paul McLeane743a472015-01-28 11:07:31 -08002417 mSpeakerDrcEnabled(false),
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07002418 mAudioPortGeneration(1),
2419 mBeaconMuteRefCount(0),
2420 mBeaconPlayingRefCount(0),
2421 mBeaconMuted(false)
Eric Laurente552edb2014-03-10 17:42:56 -07002422{
François Gaffie2110e042015-03-24 08:41:51 +01002423 audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
2424 if (!engineInstance) {
2425 ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
2426 return;
2427 }
2428 // Retrieve the Policy Manager Interface
2429 mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
2430 if (mEngine == NULL) {
2431 ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
2432 return;
2433 }
2434 mEngine->setObserver(this);
2435 status_t status = mEngine->initCheck();
2436 ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
2437
Eric Laurent6a94d692014-05-20 11:18:06 -07002438 mUidCached = getuid();
Eric Laurente552edb2014-03-10 17:42:56 -07002439 mpClientInterface = clientInterface;
2440
Paul McLeane743a472015-01-28 11:07:31 -08002441 mDefaultOutputDevice = new DeviceDescriptor(String8("Speaker"), AUDIO_DEVICE_OUT_SPEAKER);
François Gaffie53615e22015-03-19 09:24:12 +01002442 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE,
2443 mHwModules, mAvailableInputDevices, mAvailableOutputDevices,
2444 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {
2445 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE,
2446 mHwModules, mAvailableInputDevices, mAvailableOutputDevices,
2447 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {
Eric Laurente552edb2014-03-10 17:42:56 -07002448 ALOGE("could not load audio policy configuration file, setting defaults");
2449 defaultAudioPolicyConfig();
2450 }
2451 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002452 // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
Eric Laurente552edb2014-03-10 17:42:56 -07002453
François Gaffie2110e042015-03-24 08:41:51 +01002454 // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
2455 mEngine->initializeVolumeCurves(mSpeakerDrcEnabled);
Eric Laurente552edb2014-03-10 17:42:56 -07002456
2457 // open all output streams needed to access attached devices
Eric Laurent3a4311c2014-03-17 12:00:47 -07002458 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
2459 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
Eric Laurente552edb2014-03-10 17:42:56 -07002460 for (size_t i = 0; i < mHwModules.size(); i++) {
2461 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
2462 if (mHwModules[i]->mHandle == 0) {
2463 ALOGW("could not open HW module %s", mHwModules[i]->mName);
2464 continue;
2465 }
2466 // open all output streams needed to access attached devices
2467 // except for direct output streams that are only opened when they are actually
2468 // required by an app.
Eric Laurent3a4311c2014-03-17 12:00:47 -07002469 // This also validates mAvailableOutputDevices list
Eric Laurente552edb2014-03-10 17:42:56 -07002470 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2471 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002472 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002473
Eric Laurent3a4311c2014-03-17 12:00:47 -07002474 if (outProfile->mSupportedDevices.isEmpty()) {
2475 ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
2476 continue;
2477 }
2478
Eric Laurentd78f1532014-09-16 16:38:20 -07002479 if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
2480 continue;
2481 }
Eric Laurent83b88082014-06-20 18:31:16 -07002482 audio_devices_t profileType = outProfile->mSupportedDevices.types();
François Gaffie53615e22015-03-19 09:24:12 +01002483 if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
2484 profileType = mDefaultOutputDevice->type();
Eric Laurent83b88082014-06-20 18:31:16 -07002485 } else {
Eric Laurentd78f1532014-09-16 16:38:20 -07002486 // chose first device present in mSupportedDevices also part of
2487 // outputDeviceTypes
2488 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002489 profileType = outProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002490 if ((profileType & outputDeviceTypes) != 0) {
2491 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002492 }
Eric Laurente552edb2014-03-10 17:42:56 -07002493 }
2494 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002495 if ((profileType & outputDeviceTypes) == 0) {
2496 continue;
2497 }
2498 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
2499
2500 outputDesc->mDevice = profileType;
2501 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2502 config.sample_rate = outputDesc->mSamplingRate;
2503 config.channel_mask = outputDesc->mChannelMask;
2504 config.format = outputDesc->mFormat;
2505 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
2506 status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
2507 &output,
2508 &config,
2509 &outputDesc->mDevice,
2510 String8(""),
2511 &outputDesc->mLatency,
2512 outputDesc->mFlags);
2513
2514 if (status != NO_ERROR) {
2515 ALOGW("Cannot open output stream for device %08x on hw module %s",
2516 outputDesc->mDevice,
2517 mHwModules[i]->mName);
2518 } else {
2519 outputDesc->mSamplingRate = config.sample_rate;
2520 outputDesc->mChannelMask = config.channel_mask;
2521 outputDesc->mFormat = config.format;
2522
2523 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002524 audio_devices_t type = outProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002525 ssize_t index =
2526 mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
2527 // give a valid ID to an attached device once confirmed it is reachable
Paul McLeane743a472015-01-28 11:07:31 -08002528 if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
2529 mAvailableOutputDevices[index]->attach(mHwModules[i]);
Eric Laurentd78f1532014-09-16 16:38:20 -07002530 }
2531 }
2532 if (mPrimaryOutput == 0 &&
2533 outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
2534 mPrimaryOutput = output;
2535 }
2536 addOutput(output, outputDesc);
2537 setOutputDevice(output,
2538 outputDesc->mDevice,
2539 true);
2540 }
Eric Laurente552edb2014-03-10 17:42:56 -07002541 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002542 // open input streams needed to access attached devices to validate
2543 // mAvailableInputDevices list
2544 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
2545 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002546 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002547
Eric Laurent3a4311c2014-03-17 12:00:47 -07002548 if (inProfile->mSupportedDevices.isEmpty()) {
2549 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
2550 continue;
2551 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002552 // chose first device present in mSupportedDevices also part of
2553 // inputDeviceTypes
2554 audio_devices_t profileType = AUDIO_DEVICE_NONE;
2555 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002556 profileType = inProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002557 if (profileType & inputDeviceTypes) {
2558 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002559 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002560 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002561 if ((profileType & inputDeviceTypes) == 0) {
2562 continue;
2563 }
2564 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);
2565
2566 inputDesc->mInputSource = AUDIO_SOURCE_MIC;
2567 inputDesc->mDevice = profileType;
2568
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07002569 // find the address
2570 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
2571 // the inputs vector must be of size 1, but we don't want to crash here
2572 String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
2573 : String8("");
2574 ALOGV(" for input device 0x%x using address %s", profileType, address.string());
2575 ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
2576
Eric Laurentd78f1532014-09-16 16:38:20 -07002577 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2578 config.sample_rate = inputDesc->mSamplingRate;
2579 config.channel_mask = inputDesc->mChannelMask;
2580 config.format = inputDesc->mFormat;
2581 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
2582 status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,
2583 &input,
2584 &config,
2585 &inputDesc->mDevice,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07002586 address,
Eric Laurentd78f1532014-09-16 16:38:20 -07002587 AUDIO_SOURCE_MIC,
2588 AUDIO_INPUT_FLAG_NONE);
2589
2590 if (status == NO_ERROR) {
2591 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002592 audio_devices_t type = inProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002593 ssize_t index =
2594 mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
2595 // give a valid ID to an attached device once confirmed it is reachable
Paul McLeane743a472015-01-28 11:07:31 -08002596 if (index >= 0 && !mAvailableInputDevices[index]->isAttached()) {
2597 mAvailableInputDevices[index]->attach(mHwModules[i]);
Eric Laurentd78f1532014-09-16 16:38:20 -07002598 }
2599 }
2600 mpClientInterface->closeInput(input);
2601 } else {
2602 ALOGW("Cannot open input stream for device %08x on hw module %s",
2603 inputDesc->mDevice,
2604 mHwModules[i]->mName);
2605 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002606 }
2607 }
2608 // make sure all attached devices have been allocated a unique ID
2609 for (size_t i = 0; i < mAvailableOutputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08002610 if (!mAvailableOutputDevices[i]->isAttached()) {
François Gaffie53615e22015-03-19 09:24:12 +01002611 ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002612 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
2613 continue;
2614 }
François Gaffie2110e042015-03-24 08:41:51 +01002615 // The device is now validated and can be appended to the available devices of the engine
2616 mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
2617 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002618 i++;
2619 }
2620 for (size_t i = 0; i < mAvailableInputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08002621 if (!mAvailableInputDevices[i]->isAttached()) {
François Gaffie53615e22015-03-19 09:24:12 +01002622 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002623 mAvailableInputDevices.remove(mAvailableInputDevices[i]);
2624 continue;
2625 }
François Gaffie2110e042015-03-24 08:41:51 +01002626 // The device is now validated and can be appended to the available devices of the engine
2627 mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
2628 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002629 i++;
2630 }
2631 // make sure default device is reachable
2632 if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
François Gaffie53615e22015-03-19 09:24:12 +01002633 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002634 }
Eric Laurente552edb2014-03-10 17:42:56 -07002635
2636 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
2637
2638 updateDevicesAndOutputs();
2639
2640#ifdef AUDIO_POLICY_TEST
2641 if (mPrimaryOutput != 0) {
2642 AudioParameter outputCmd = AudioParameter();
2643 outputCmd.addInt(String8("set_id"), 0);
2644 mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
2645
2646 mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
2647 mTestSamplingRate = 44100;
Eric Laurent3b73df72014-03-11 09:06:29 -07002648 mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
2649 mTestChannels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07002650 mTestLatencyMs = 0;
2651 mCurOutput = 0;
2652 mDirectOutput = false;
2653 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
2654 mTestOutputs[i] = 0;
2655 }
2656
2657 const size_t SIZE = 256;
2658 char buffer[SIZE];
2659 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
2660 run(buffer, ANDROID_PRIORITY_AUDIO);
2661 }
2662#endif //AUDIO_POLICY_TEST
2663}
2664
Eric Laurente0720872014-03-11 09:30:41 -07002665AudioPolicyManager::~AudioPolicyManager()
Eric Laurente552edb2014-03-10 17:42:56 -07002666{
2667#ifdef AUDIO_POLICY_TEST
2668 exit();
2669#endif //AUDIO_POLICY_TEST
2670 for (size_t i = 0; i < mOutputs.size(); i++) {
2671 mpClientInterface->closeOutput(mOutputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002672 }
2673 for (size_t i = 0; i < mInputs.size(); i++) {
2674 mpClientInterface->closeInput(mInputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002675 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002676 mAvailableOutputDevices.clear();
2677 mAvailableInputDevices.clear();
Eric Laurent1f2f2232014-06-02 12:01:23 -07002678 mOutputs.clear();
2679 mInputs.clear();
2680 mHwModules.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07002681}
2682
Eric Laurente0720872014-03-11 09:30:41 -07002683status_t AudioPolicyManager::initCheck()
Eric Laurente552edb2014-03-10 17:42:56 -07002684{
2685 return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
2686}
2687
2688#ifdef AUDIO_POLICY_TEST
Eric Laurente0720872014-03-11 09:30:41 -07002689bool AudioPolicyManager::threadLoop()
Eric Laurente552edb2014-03-10 17:42:56 -07002690{
2691 ALOGV("entering threadLoop()");
2692 while (!exitPending())
2693 {
2694 String8 command;
2695 int valueInt;
2696 String8 value;
2697
2698 Mutex::Autolock _l(mLock);
2699 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
2700
2701 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
2702 AudioParameter param = AudioParameter(command);
2703
2704 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
2705 valueInt != 0) {
2706 ALOGV("Test command %s received", command.string());
2707 String8 target;
2708 if (param.get(String8("target"), target) != NO_ERROR) {
2709 target = "Manager";
2710 }
2711 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
2712 param.remove(String8("test_cmd_policy_output"));
2713 mCurOutput = valueInt;
2714 }
2715 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
2716 param.remove(String8("test_cmd_policy_direct"));
2717 if (value == "false") {
2718 mDirectOutput = false;
2719 } else if (value == "true") {
2720 mDirectOutput = true;
2721 }
2722 }
2723 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
2724 param.remove(String8("test_cmd_policy_input"));
2725 mTestInput = valueInt;
2726 }
2727
2728 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
2729 param.remove(String8("test_cmd_policy_format"));
Eric Laurent3b73df72014-03-11 09:06:29 -07002730 int format = AUDIO_FORMAT_INVALID;
Eric Laurente552edb2014-03-10 17:42:56 -07002731 if (value == "PCM 16 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002732 format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07002733 } else if (value == "PCM 8 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002734 format = AUDIO_FORMAT_PCM_8_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07002735 } else if (value == "Compressed MP3") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002736 format = AUDIO_FORMAT_MP3;
Eric Laurente552edb2014-03-10 17:42:56 -07002737 }
Eric Laurent3b73df72014-03-11 09:06:29 -07002738 if (format != AUDIO_FORMAT_INVALID) {
Eric Laurente552edb2014-03-10 17:42:56 -07002739 if (target == "Manager") {
2740 mTestFormat = format;
2741 } else if (mTestOutputs[mCurOutput] != 0) {
2742 AudioParameter outputParam = AudioParameter();
2743 outputParam.addInt(String8("format"), format);
2744 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2745 }
2746 }
2747 }
2748 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
2749 param.remove(String8("test_cmd_policy_channels"));
2750 int channels = 0;
2751
2752 if (value == "Channels Stereo") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002753 channels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07002754 } else if (value == "Channels Mono") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002755 channels = AUDIO_CHANNEL_OUT_MONO;
Eric Laurente552edb2014-03-10 17:42:56 -07002756 }
2757 if (channels != 0) {
2758 if (target == "Manager") {
2759 mTestChannels = channels;
2760 } else if (mTestOutputs[mCurOutput] != 0) {
2761 AudioParameter outputParam = AudioParameter();
2762 outputParam.addInt(String8("channels"), channels);
2763 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2764 }
2765 }
2766 }
2767 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
2768 param.remove(String8("test_cmd_policy_sampleRate"));
2769 if (valueInt >= 0 && valueInt <= 96000) {
2770 int samplingRate = valueInt;
2771 if (target == "Manager") {
2772 mTestSamplingRate = samplingRate;
2773 } else if (mTestOutputs[mCurOutput] != 0) {
2774 AudioParameter outputParam = AudioParameter();
2775 outputParam.addInt(String8("sampling_rate"), samplingRate);
2776 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2777 }
2778 }
2779 }
2780
2781 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
2782 param.remove(String8("test_cmd_policy_reopen"));
2783
Eric Laurent1f2f2232014-06-02 12:01:23 -07002784 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07002785 mpClientInterface->closeOutput(mPrimaryOutput);
2786
2787 audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
2788
François Gaffie53615e22015-03-19 09:24:12 +01002789 removeOutput(mPrimaryOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07002790 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
Eric Laurente552edb2014-03-10 17:42:56 -07002791 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurentcf2c0212014-07-25 16:20:43 -07002792 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2793 config.sample_rate = outputDesc->mSamplingRate;
2794 config.channel_mask = outputDesc->mChannelMask;
2795 config.format = outputDesc->mFormat;
2796 status_t status = mpClientInterface->openOutput(moduleHandle,
2797 &mPrimaryOutput,
2798 &config,
2799 &outputDesc->mDevice,
2800 String8(""),
2801 &outputDesc->mLatency,
2802 outputDesc->mFlags);
2803 if (status != NO_ERROR) {
2804 ALOGE("Failed to reopen hardware output stream, "
2805 "samplingRate: %d, format %d, channels %d",
2806 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
Eric Laurente552edb2014-03-10 17:42:56 -07002807 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07002808 outputDesc->mSamplingRate = config.sample_rate;
2809 outputDesc->mChannelMask = config.channel_mask;
2810 outputDesc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07002811 AudioParameter outputCmd = AudioParameter();
2812 outputCmd.addInt(String8("set_id"), 0);
2813 mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
2814 addOutput(mPrimaryOutput, outputDesc);
2815 }
2816 }
2817
2818
2819 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
2820 }
2821 }
2822 return false;
2823}
2824
Eric Laurente0720872014-03-11 09:30:41 -07002825void AudioPolicyManager::exit()
Eric Laurente552edb2014-03-10 17:42:56 -07002826{
2827 {
2828 AutoMutex _l(mLock);
2829 requestExit();
2830 mWaitWorkCV.signal();
2831 }
2832 requestExitAndWait();
2833}
2834
Eric Laurente0720872014-03-11 09:30:41 -07002835int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07002836{
2837 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
2838 if (output == mTestOutputs[i]) return i;
2839 }
2840 return 0;
2841}
2842#endif //AUDIO_POLICY_TEST
2843
2844// ---
2845
Eric Laurent1f2f2232014-06-02 12:01:23 -07002846void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc)
Eric Laurente552edb2014-03-10 17:42:56 -07002847{
François Gaffie98cc1912015-03-18 17:52:40 +01002848 outputDesc->setIoHandle(output);
Eric Laurent1c333e22014-05-20 10:48:17 -07002849 mOutputs.add(output, outputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07002850 nextAudioPortGeneration();
Eric Laurente552edb2014-03-10 17:42:56 -07002851}
2852
François Gaffie53615e22015-03-19 09:24:12 +01002853void AudioPolicyManager::removeOutput(audio_io_handle_t output)
2854{
2855 mOutputs.removeItem(output);
2856}
2857
Eric Laurent1f2f2232014-06-02 12:01:23 -07002858void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc)
Eric Laurentd4692962014-05-05 18:13:44 -07002859{
François Gaffie98cc1912015-03-18 17:52:40 +01002860 inputDesc->setIoHandle(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07002861 mInputs.add(input, inputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07002862 nextAudioPortGeneration();
Eric Laurentd4692962014-05-05 18:13:44 -07002863}
Eric Laurente552edb2014-03-10 17:42:56 -07002864
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002865void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
keunyoung3190e672014-12-30 13:00:52 -08002866 const audio_devices_t device /*in*/,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002867 const String8 address /*in*/,
2868 SortedVector<audio_io_handle_t>& outputs /*out*/) {
keunyoung3190e672014-12-30 13:00:52 -08002869 sp<DeviceDescriptor> devDesc =
2870 desc->mProfile->mSupportedDevices.getDevice(device, address);
2871 if (devDesc != 0) {
2872 ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
2873 desc->mIoHandle, address.string());
2874 outputs.add(desc->mIoHandle);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002875 }
2876}
2877
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07002878status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
François Gaffie53615e22015-03-19 09:24:12 +01002879 audio_policy_dev_state_t state,
2880 SortedVector<audio_io_handle_t>& outputs,
2881 const String8 address)
Eric Laurente552edb2014-03-10 17:42:56 -07002882{
François Gaffie53615e22015-03-19 09:24:12 +01002883 audio_devices_t device = devDesc->type();
Eric Laurent1f2f2232014-06-02 12:01:23 -07002884 sp<AudioOutputDescriptor> desc;
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07002885 // erase all current sample rates, formats and channel masks
2886 devDesc->clearCapabilities();
Eric Laurente552edb2014-03-10 17:42:56 -07002887
Eric Laurent3b73df72014-03-11 09:06:29 -07002888 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
Eric Laurente552edb2014-03-10 17:42:56 -07002889 // first list already open outputs that can be routed to this device
2890 for (size_t i = 0; i < mOutputs.size(); i++) {
2891 desc = mOutputs.valueAt(i);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002892 if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
François Gaffie53615e22015-03-19 09:24:12 +01002893 if (!device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002894 ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
2895 outputs.add(mOutputs.keyAt(i));
2896 } else {
2897 ALOGV(" checking address match due to device 0x%x", device);
keunyoung3190e672014-12-30 13:00:52 -08002898 findIoHandlesByAddress(desc, device, address, outputs);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002899 }
Eric Laurente552edb2014-03-10 17:42:56 -07002900 }
2901 }
2902 // then look for output profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07002903 SortedVector< sp<IOProfile> > profiles;
Eric Laurente552edb2014-03-10 17:42:56 -07002904 for (size_t i = 0; i < mHwModules.size(); i++)
2905 {
2906 if (mHwModules[i]->mHandle == 0) {
2907 continue;
2908 }
2909 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2910 {
Eric Laurent275e8e92014-11-30 15:14:47 -08002911 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
2912 if (profile->mSupportedDevices.types() & device) {
François Gaffie53615e22015-03-19 09:24:12 +01002913 if (!device_distinguishes_on_address(device) ||
Eric Laurent275e8e92014-11-30 15:14:47 -08002914 address == profile->mSupportedDevices[0]->mAddress) {
2915 profiles.add(profile);
2916 ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
2917 }
Eric Laurente552edb2014-03-10 17:42:56 -07002918 }
2919 }
2920 }
2921
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002922 ALOGV(" found %d profiles, %d outputs", profiles.size(), outputs.size());
2923
Eric Laurente552edb2014-03-10 17:42:56 -07002924 if (profiles.isEmpty() && outputs.isEmpty()) {
2925 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
2926 return BAD_VALUE;
2927 }
2928
2929 // open outputs for matching profiles if needed. Direct outputs are also opened to
2930 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
2931 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002932 sp<IOProfile> profile = profiles[profile_index];
Eric Laurente552edb2014-03-10 17:42:56 -07002933
2934 // nothing to do if one output is already opened for this profile
2935 size_t j;
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002936 for (j = 0; j < outputs.size(); j++) {
2937 desc = mOutputs.valueFor(outputs.itemAt(j));
Eric Laurente552edb2014-03-10 17:42:56 -07002938 if (!desc->isDuplicated() && desc->mProfile == profile) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07002939 // matching profile: save the sample rates, format and channel masks supported
2940 // by the profile in our device descriptor
2941 devDesc->importAudioPort(profile);
Eric Laurente552edb2014-03-10 17:42:56 -07002942 break;
2943 }
2944 }
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002945 if (j != outputs.size()) {
Eric Laurente552edb2014-03-10 17:42:56 -07002946 continue;
2947 }
2948
Eric Laurent83b88082014-06-20 18:31:16 -07002949 ALOGV("opening output for device %08x with params %s profile %p",
2950 device, address.string(), profile.get());
Eric Laurente552edb2014-03-10 17:42:56 -07002951 desc = new AudioOutputDescriptor(profile);
2952 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07002953 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2954 config.sample_rate = desc->mSamplingRate;
2955 config.channel_mask = desc->mChannelMask;
2956 config.format = desc->mFormat;
2957 config.offload_info.sample_rate = desc->mSamplingRate;
2958 config.offload_info.channel_mask = desc->mChannelMask;
2959 config.offload_info.format = desc->mFormat;
2960 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
2961 status_t status = mpClientInterface->openOutput(profile->mModule->mHandle,
2962 &output,
2963 &config,
2964 &desc->mDevice,
2965 address,
2966 &desc->mLatency,
2967 desc->mFlags);
2968 if (status == NO_ERROR) {
2969 desc->mSamplingRate = config.sample_rate;
2970 desc->mChannelMask = config.channel_mask;
2971 desc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07002972
Eric Laurentd4692962014-05-05 18:13:44 -07002973 // Here is where the out_set_parameters() for card & device gets called
Eric Laurent3a4311c2014-03-17 12:00:47 -07002974 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07002975 char *param = audio_device_address_to_parameter(device, address);
2976 mpClientInterface->setParameters(output, String8(param));
2977 free(param);
Eric Laurente552edb2014-03-10 17:42:56 -07002978 }
2979
Eric Laurentd4692962014-05-05 18:13:44 -07002980 // Here is where we step through and resolve any "dynamic" fields
2981 String8 reply;
2982 char *value;
2983 if (profile->mSamplingRates[0] == 0) {
2984 reply = mpClientInterface->getParameters(output,
2985 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002986 ALOGV("checkOutputsForDevice() supported sampling rates %s",
Eric Laurentd4692962014-05-05 18:13:44 -07002987 reply.string());
2988 value = strpbrk((char *)reply.string(), "=");
2989 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002990 profile->loadSamplingRates(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07002991 }
Eric Laurentd4692962014-05-05 18:13:44 -07002992 }
2993 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
2994 reply = mpClientInterface->getParameters(output,
2995 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002996 ALOGV("checkOutputsForDevice() supported formats %s",
Eric Laurentd4692962014-05-05 18:13:44 -07002997 reply.string());
2998 value = strpbrk((char *)reply.string(), "=");
2999 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003000 profile->loadFormats(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003001 }
Eric Laurentd4692962014-05-05 18:13:44 -07003002 }
3003 if (profile->mChannelMasks[0] == 0) {
3004 reply = mpClientInterface->getParameters(output,
3005 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003006 ALOGV("checkOutputsForDevice() supported channel masks %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003007 reply.string());
3008 value = strpbrk((char *)reply.string(), "=");
3009 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003010 profile->loadOutChannels(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003011 }
Eric Laurentd4692962014-05-05 18:13:44 -07003012 }
3013 if (((profile->mSamplingRates[0] == 0) &&
3014 (profile->mSamplingRates.size() < 2)) ||
3015 ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
3016 (profile->mFormats.size() < 2)) ||
3017 ((profile->mChannelMasks[0] == 0) &&
3018 (profile->mChannelMasks.size() < 2))) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003019 ALOGW("checkOutputsForDevice() missing param");
Eric Laurentd4692962014-05-05 18:13:44 -07003020 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003021 output = AUDIO_IO_HANDLE_NONE;
Eric Laurent1e693b52014-07-09 15:03:28 -07003022 } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 ||
3023 profile->mChannelMasks[0] == 0) {
Eric Laurentd4692962014-05-05 18:13:44 -07003024 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003025 config.sample_rate = profile->pickSamplingRate();
3026 config.channel_mask = profile->pickChannelMask();
3027 config.format = profile->pickFormat();
3028 config.offload_info.sample_rate = config.sample_rate;
3029 config.offload_info.channel_mask = config.channel_mask;
3030 config.offload_info.format = config.format;
3031 status = mpClientInterface->openOutput(profile->mModule->mHandle,
3032 &output,
3033 &config,
3034 &desc->mDevice,
3035 address,
3036 &desc->mLatency,
3037 desc->mFlags);
3038 if (status == NO_ERROR) {
3039 desc->mSamplingRate = config.sample_rate;
3040 desc->mChannelMask = config.channel_mask;
3041 desc->mFormat = config.format;
3042 } else {
3043 output = AUDIO_IO_HANDLE_NONE;
3044 }
Eric Laurentd4692962014-05-05 18:13:44 -07003045 }
3046
Eric Laurentcf2c0212014-07-25 16:20:43 -07003047 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003048 addOutput(output, desc);
François Gaffie53615e22015-03-19 09:24:12 +01003049 if (device_distinguishes_on_address(device) && address != "0") {
François Gaffie036e1e92015-03-19 10:16:24 +01003050 sp<AudioPolicyMix> policyMix;
3051 if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08003052 ALOGE("checkOutputsForDevice() cannot find policy for address %s",
3053 address.string());
3054 }
François Gaffie036e1e92015-03-19 10:16:24 +01003055 policyMix->setOutput(desc);
3056 desc->mPolicyMix = &(policyMix->getMix());
3057
Eric Laurentc722f302014-12-10 11:21:49 -08003058 } else if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
3059 // no duplicated output for direct outputs and
3060 // outputs used by dynamic policy mixes
Eric Laurentcf2c0212014-07-25 16:20:43 -07003061 audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003062
Eric Laurentd4692962014-05-05 18:13:44 -07003063 // set initial stream volume for device
3064 applyStreamVolumes(output, device, 0, true);
Eric Laurente552edb2014-03-10 17:42:56 -07003065
Eric Laurentd4692962014-05-05 18:13:44 -07003066 //TODO: configure audio effect output stage here
3067
3068 // open a duplicating output thread for the new output and the primary output
3069 duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
3070 mPrimaryOutput);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003071 if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003072 // add duplicated output descriptor
Eric Laurentcf2c0212014-07-25 16:20:43 -07003073 sp<AudioOutputDescriptor> dupOutputDesc =
3074 new AudioOutputDescriptor(NULL);
Eric Laurentd4692962014-05-05 18:13:44 -07003075 dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
3076 dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
3077 dupOutputDesc->mSamplingRate = desc->mSamplingRate;
3078 dupOutputDesc->mFormat = desc->mFormat;
3079 dupOutputDesc->mChannelMask = desc->mChannelMask;
3080 dupOutputDesc->mLatency = desc->mLatency;
3081 addOutput(duplicatedOutput, dupOutputDesc);
3082 applyStreamVolumes(duplicatedOutput, device, 0, true);
3083 } else {
3084 ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
3085 mPrimaryOutput, output);
3086 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01003087 removeOutput(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07003088 nextAudioPortGeneration();
Eric Laurentcf2c0212014-07-25 16:20:43 -07003089 output = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003090 }
Eric Laurente552edb2014-03-10 17:42:56 -07003091 }
3092 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003093 } else {
3094 output = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003095 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003096 if (output == AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003097 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07003098 profiles.removeAt(profile_index);
3099 profile_index--;
3100 } else {
3101 outputs.add(output);
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003102 devDesc->importAudioPort(profile);
3103
François Gaffie53615e22015-03-19 09:24:12 +01003104 if (device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003105 ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
3106 device, address.string());
3107 setOutputDevice(output, device, true/*force*/, 0/*delay*/,
3108 NULL/*patch handle*/, address.string());
3109 }
Eric Laurente552edb2014-03-10 17:42:56 -07003110 ALOGV("checkOutputsForDevice(): adding output %d", output);
3111 }
3112 }
3113
3114 if (profiles.isEmpty()) {
3115 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3116 return BAD_VALUE;
3117 }
Eric Laurentd4692962014-05-05 18:13:44 -07003118 } else { // Disconnect
Eric Laurente552edb2014-03-10 17:42:56 -07003119 // check if one opened output is not needed any more after disconnecting one device
3120 for (size_t i = 0; i < mOutputs.size(); i++) {
3121 desc = mOutputs.valueAt(i);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003122 if (!desc->isDuplicated()) {
Eric Laurent275e8e92014-11-30 15:14:47 -08003123 // exact match on device
François Gaffie53615e22015-03-19 09:24:12 +01003124 if (device_distinguishes_on_address(device) &&
Eric Laurent275e8e92014-11-30 15:14:47 -08003125 (desc->mProfile->mSupportedDevices.types() == device)) {
keunyoung3190e672014-12-30 13:00:52 -08003126 findIoHandlesByAddress(desc, device, address, outputs);
Eric Laurent275e8e92014-11-30 15:14:47 -08003127 } else if (!(desc->mProfile->mSupportedDevices.types()
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003128 & mAvailableOutputDevices.types())) {
3129 ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
3130 mOutputs.keyAt(i));
3131 outputs.add(mOutputs.keyAt(i));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003132 }
Eric Laurente552edb2014-03-10 17:42:56 -07003133 }
3134 }
Eric Laurentd4692962014-05-05 18:13:44 -07003135 // Clear any profiles associated with the disconnected device.
Eric Laurente552edb2014-03-10 17:42:56 -07003136 for (size_t i = 0; i < mHwModules.size(); i++)
3137 {
3138 if (mHwModules[i]->mHandle == 0) {
3139 continue;
3140 }
3141 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3142 {
Eric Laurent1c333e22014-05-20 10:48:17 -07003143 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07003144 if (profile->mSupportedDevices.types() & device) {
3145 ALOGV("checkOutputsForDevice(): "
3146 "clearing direct output profile %zu on module %zu", j, i);
Eric Laurente552edb2014-03-10 17:42:56 -07003147 if (profile->mSamplingRates[0] == 0) {
3148 profile->mSamplingRates.clear();
3149 profile->mSamplingRates.add(0);
3150 }
3151 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3152 profile->mFormats.clear();
3153 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3154 }
3155 if (profile->mChannelMasks[0] == 0) {
3156 profile->mChannelMasks.clear();
3157 profile->mChannelMasks.add(0);
3158 }
3159 }
3160 }
3161 }
3162 }
3163 return NO_ERROR;
3164}
3165
Eric Laurentd4692962014-05-05 18:13:44 -07003166status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +01003167 audio_policy_dev_state_t state,
3168 SortedVector<audio_io_handle_t>& inputs,
3169 const String8 address)
Eric Laurentd4692962014-05-05 18:13:44 -07003170{
Eric Laurent1f2f2232014-06-02 12:01:23 -07003171 sp<AudioInputDescriptor> desc;
Eric Laurentd4692962014-05-05 18:13:44 -07003172 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3173 // first list already open inputs that can be routed to this device
3174 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3175 desc = mInputs.valueAt(input_index);
3176 if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
3177 ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
3178 inputs.add(mInputs.keyAt(input_index));
3179 }
3180 }
3181
3182 // then look for input profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07003183 SortedVector< sp<IOProfile> > profiles;
Eric Laurentd4692962014-05-05 18:13:44 -07003184 for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
3185 {
3186 if (mHwModules[module_idx]->mHandle == 0) {
3187 continue;
3188 }
3189 for (size_t profile_index = 0;
3190 profile_index < mHwModules[module_idx]->mInputProfiles.size();
3191 profile_index++)
3192 {
Eric Laurent275e8e92014-11-30 15:14:47 -08003193 sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
3194
3195 if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
François Gaffie53615e22015-03-19 09:24:12 +01003196 if (!device_distinguishes_on_address(device) ||
Eric Laurent275e8e92014-11-30 15:14:47 -08003197 address == profile->mSupportedDevices[0]->mAddress) {
3198 profiles.add(profile);
3199 ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
3200 profile_index, module_idx);
3201 }
Eric Laurentd4692962014-05-05 18:13:44 -07003202 }
3203 }
3204 }
3205
3206 if (profiles.isEmpty() && inputs.isEmpty()) {
3207 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3208 return BAD_VALUE;
3209 }
3210
3211 // open inputs for matching profiles if needed. Direct inputs are also opened to
3212 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3213 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
3214
Eric Laurent1c333e22014-05-20 10:48:17 -07003215 sp<IOProfile> profile = profiles[profile_index];
Eric Laurentd4692962014-05-05 18:13:44 -07003216 // nothing to do if one input is already opened for this profile
3217 size_t input_index;
3218 for (input_index = 0; input_index < mInputs.size(); input_index++) {
3219 desc = mInputs.valueAt(input_index);
3220 if (desc->mProfile == profile) {
3221 break;
3222 }
3223 }
3224 if (input_index != mInputs.size()) {
3225 continue;
3226 }
3227
3228 ALOGV("opening input for device 0x%X with params %s", device, address.string());
3229 desc = new AudioInputDescriptor(profile);
3230 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003231 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3232 config.sample_rate = desc->mSamplingRate;
3233 config.channel_mask = desc->mChannelMask;
3234 config.format = desc->mFormat;
3235 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3236 status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
3237 &input,
3238 &config,
3239 &desc->mDevice,
3240 address,
3241 AUDIO_SOURCE_MIC,
3242 AUDIO_INPUT_FLAG_NONE /*FIXME*/);
Eric Laurentd4692962014-05-05 18:13:44 -07003243
Eric Laurentcf2c0212014-07-25 16:20:43 -07003244 if (status == NO_ERROR) {
3245 desc->mSamplingRate = config.sample_rate;
3246 desc->mChannelMask = config.channel_mask;
3247 desc->mFormat = config.format;
Eric Laurentd4692962014-05-05 18:13:44 -07003248
Eric Laurentd4692962014-05-05 18:13:44 -07003249 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003250 char *param = audio_device_address_to_parameter(device, address);
3251 mpClientInterface->setParameters(input, String8(param));
3252 free(param);
Eric Laurentd4692962014-05-05 18:13:44 -07003253 }
3254
3255 // Here is where we step through and resolve any "dynamic" fields
3256 String8 reply;
3257 char *value;
3258 if (profile->mSamplingRates[0] == 0) {
3259 reply = mpClientInterface->getParameters(input,
3260 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
3261 ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
3262 reply.string());
3263 value = strpbrk((char *)reply.string(), "=");
3264 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003265 profile->loadSamplingRates(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003266 }
3267 }
3268 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3269 reply = mpClientInterface->getParameters(input,
3270 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
3271 ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
3272 value = strpbrk((char *)reply.string(), "=");
3273 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003274 profile->loadFormats(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003275 }
3276 }
3277 if (profile->mChannelMasks[0] == 0) {
3278 reply = mpClientInterface->getParameters(input,
3279 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
3280 ALOGV("checkInputsForDevice() direct input sup channel masks %s",
3281 reply.string());
3282 value = strpbrk((char *)reply.string(), "=");
3283 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003284 profile->loadInChannels(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003285 }
3286 }
3287 if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
3288 ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
3289 ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
3290 ALOGW("checkInputsForDevice() direct input missing param");
3291 mpClientInterface->closeInput(input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003292 input = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003293 }
3294
3295 if (input != 0) {
3296 addInput(input, desc);
3297 }
3298 } // endif input != 0
3299
Eric Laurentcf2c0212014-07-25 16:20:43 -07003300 if (input == AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003301 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
Eric Laurentd4692962014-05-05 18:13:44 -07003302 profiles.removeAt(profile_index);
3303 profile_index--;
3304 } else {
3305 inputs.add(input);
3306 ALOGV("checkInputsForDevice(): adding input %d", input);
3307 }
3308 } // end scan profiles
3309
3310 if (profiles.isEmpty()) {
3311 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3312 return BAD_VALUE;
3313 }
3314 } else {
3315 // Disconnect
3316 // check if one opened input is not needed any more after disconnecting one device
3317 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3318 desc = mInputs.valueAt(input_index);
Eric Laurentddbc6652014-11-13 15:13:44 -08003319 if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types() &
3320 ~AUDIO_DEVICE_BIT_IN)) {
Eric Laurentd4692962014-05-05 18:13:44 -07003321 ALOGV("checkInputsForDevice(): disconnecting adding input %d",
3322 mInputs.keyAt(input_index));
3323 inputs.add(mInputs.keyAt(input_index));
3324 }
3325 }
3326 // Clear any profiles associated with the disconnected device.
3327 for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
3328 if (mHwModules[module_index]->mHandle == 0) {
3329 continue;
3330 }
3331 for (size_t profile_index = 0;
3332 profile_index < mHwModules[module_index]->mInputProfiles.size();
3333 profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003334 sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
Eric Laurentddbc6652014-11-13 15:13:44 -08003335 if (profile->mSupportedDevices.types() & device & ~AUDIO_DEVICE_BIT_IN) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07003336 ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
Eric Laurentd4692962014-05-05 18:13:44 -07003337 profile_index, module_index);
3338 if (profile->mSamplingRates[0] == 0) {
3339 profile->mSamplingRates.clear();
3340 profile->mSamplingRates.add(0);
3341 }
3342 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3343 profile->mFormats.clear();
3344 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3345 }
3346 if (profile->mChannelMasks[0] == 0) {
3347 profile->mChannelMasks.clear();
3348 profile->mChannelMasks.add(0);
3349 }
3350 }
3351 }
3352 }
3353 } // end disconnect
3354
3355 return NO_ERROR;
3356}
3357
3358
Eric Laurente0720872014-03-11 09:30:41 -07003359void AudioPolicyManager::closeOutput(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07003360{
3361 ALOGV("closeOutput(%d)", output);
3362
Eric Laurent1f2f2232014-06-02 12:01:23 -07003363 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003364 if (outputDesc == NULL) {
3365 ALOGW("closeOutput() unknown output %d", output);
3366 return;
3367 }
François Gaffie036e1e92015-03-19 10:16:24 +01003368 mPolicyMixes.closeOutput(outputDesc);
Eric Laurent275e8e92014-11-30 15:14:47 -08003369
Eric Laurente552edb2014-03-10 17:42:56 -07003370 // look for duplicated outputs connected to the output being removed.
3371 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003372 sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07003373 if (dupOutputDesc->isDuplicated() &&
3374 (dupOutputDesc->mOutput1 == outputDesc ||
3375 dupOutputDesc->mOutput2 == outputDesc)) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003376 sp<AudioOutputDescriptor> outputDesc2;
Eric Laurente552edb2014-03-10 17:42:56 -07003377 if (dupOutputDesc->mOutput1 == outputDesc) {
3378 outputDesc2 = dupOutputDesc->mOutput2;
3379 } else {
3380 outputDesc2 = dupOutputDesc->mOutput1;
3381 }
3382 // As all active tracks on duplicated output will be deleted,
3383 // and as they were also referenced on the other output, the reference
3384 // count for their stream type must be adjusted accordingly on
3385 // the other output.
Eric Laurent3b73df72014-03-11 09:06:29 -07003386 for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
Eric Laurente552edb2014-03-10 17:42:56 -07003387 int refCount = dupOutputDesc->mRefCount[j];
Eric Laurent3b73df72014-03-11 09:06:29 -07003388 outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
Eric Laurente552edb2014-03-10 17:42:56 -07003389 }
3390 audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
3391 ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
3392
3393 mpClientInterface->closeOutput(duplicatedOutput);
François Gaffie53615e22015-03-19 09:24:12 +01003394 removeOutput(duplicatedOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07003395 }
3396 }
3397
Eric Laurent05b90f82014-08-27 15:32:29 -07003398 nextAudioPortGeneration();
3399
3400 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3401 if (index >= 0) {
3402 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3403 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3404 mAudioPatches.removeItemsAt(index);
3405 mpClientInterface->onAudioPatchListUpdate();
3406 }
3407
Eric Laurente552edb2014-03-10 17:42:56 -07003408 AudioParameter param;
3409 param.add(String8("closing"), String8("true"));
3410 mpClientInterface->setParameters(output, param.toString());
3411
3412 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01003413 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003414 mPreviousOutputs = mOutputs;
Eric Laurent05b90f82014-08-27 15:32:29 -07003415}
3416
3417void AudioPolicyManager::closeInput(audio_io_handle_t input)
3418{
3419 ALOGV("closeInput(%d)", input);
3420
3421 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
3422 if (inputDesc == NULL) {
3423 ALOGW("closeInput() unknown input %d", input);
3424 return;
3425 }
3426
Eric Laurent6a94d692014-05-20 11:18:06 -07003427 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07003428
3429 ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
3430 if (index >= 0) {
3431 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3432 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3433 mAudioPatches.removeItemsAt(index);
3434 mpClientInterface->onAudioPatchListUpdate();
3435 }
3436
3437 mpClientInterface->closeInput(input);
3438 mInputs.removeItem(input);
Eric Laurente552edb2014-03-10 17:42:56 -07003439}
3440
Eric Laurente0720872014-03-11 09:30:41 -07003441SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +01003442 AudioOutputCollection openOutputs)
Eric Laurente552edb2014-03-10 17:42:56 -07003443{
3444 SortedVector<audio_io_handle_t> outputs;
3445
3446 ALOGVV("getOutputsForDevice() device %04x", device);
3447 for (size_t i = 0; i < openOutputs.size(); i++) {
3448 ALOGVV("output %d isDuplicated=%d device=%04x",
3449 i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
3450 if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
3451 ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
3452 outputs.add(openOutputs.keyAt(i));
3453 }
3454 }
3455 return outputs;
3456}
3457
Eric Laurente0720872014-03-11 09:30:41 -07003458bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
François Gaffie53615e22015-03-19 09:24:12 +01003459 SortedVector<audio_io_handle_t>& outputs2)
Eric Laurente552edb2014-03-10 17:42:56 -07003460{
3461 if (outputs1.size() != outputs2.size()) {
3462 return false;
3463 }
3464 for (size_t i = 0; i < outputs1.size(); i++) {
3465 if (outputs1[i] != outputs2[i]) {
3466 return false;
3467 }
3468 }
3469 return true;
3470}
3471
Eric Laurente0720872014-03-11 09:30:41 -07003472void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
Eric Laurente552edb2014-03-10 17:42:56 -07003473{
3474 audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
3475 audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
3476 SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
3477 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
3478
Jean-Michel Trivife472e22014-12-16 14:23:13 -08003479 // also take into account external policy-related changes: add all outputs which are
3480 // associated with policies in the "before" and "after" output vectors
3481 ALOGVV("checkOutputForStrategy(): policy related outputs");
3482 for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
3483 const sp<AudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
3484 if (desc != 0 && desc->mPolicyMix != NULL) {
3485 srcOutputs.add(desc->mIoHandle);
3486 ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
3487 }
3488 }
3489 for (size_t i = 0 ; i < mOutputs.size() ; i++) {
3490 const sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
3491 if (desc != 0 && desc->mPolicyMix != NULL) {
3492 dstOutputs.add(desc->mIoHandle);
3493 ALOGVV(" new outputs: adding %d", desc->mIoHandle);
3494 }
3495 }
3496
Eric Laurente552edb2014-03-10 17:42:56 -07003497 if (!vectorsEqual(srcOutputs,dstOutputs)) {
3498 ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
3499 strategy, srcOutputs[0], dstOutputs[0]);
3500 // mute strategy while moving tracks from one output to another
3501 for (size_t i = 0; i < srcOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003502 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
François Gaffiead3183e2015-03-18 16:55:35 +01003503 if (isStrategyActive(desc, strategy)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003504 setStrategyMute(strategy, true, srcOutputs[i]);
3505 setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
3506 }
3507 }
3508
3509 // Move effects associated to this strategy from previous output to new output
3510 if (strategy == STRATEGY_MEDIA) {
3511 audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
3512 SortedVector<audio_io_handle_t> moved;
3513 for (size_t i = 0; i < mEffects.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003514 sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
3515 if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
3516 effectDesc->mIo != fxOutput) {
3517 if (moved.indexOf(effectDesc->mIo) < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07003518 ALOGV("checkOutputForStrategy() moving effect %d to output %d",
3519 mEffects.keyAt(i), fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003520 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
Eric Laurente552edb2014-03-10 17:42:56 -07003521 fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003522 moved.add(effectDesc->mIo);
Eric Laurente552edb2014-03-10 17:42:56 -07003523 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07003524 effectDesc->mIo = fxOutput;
Eric Laurente552edb2014-03-10 17:42:56 -07003525 }
3526 }
3527 }
3528 // Move tracks associated to this strategy from previous output to new output
Eric Laurent3b73df72014-03-11 09:06:29 -07003529 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08003530 if (i == AUDIO_STREAM_PATCH) {
3531 continue;
3532 }
Eric Laurent3b73df72014-03-11 09:06:29 -07003533 if (getStrategy((audio_stream_type_t)i) == strategy) {
3534 mpClientInterface->invalidateStream((audio_stream_type_t)i);
Eric Laurente552edb2014-03-10 17:42:56 -07003535 }
3536 }
3537 }
3538}
3539
Eric Laurente0720872014-03-11 09:30:41 -07003540void AudioPolicyManager::checkOutputForAllStrategies()
Eric Laurente552edb2014-03-10 17:42:56 -07003541{
François Gaffie2110e042015-03-24 08:41:51 +01003542 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05003543 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07003544 checkOutputForStrategy(STRATEGY_PHONE);
François Gaffie2110e042015-03-24 08:41:51 +01003545 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05003546 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07003547 checkOutputForStrategy(STRATEGY_SONIFICATION);
3548 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
Eric Laurent223fd5c2014-11-11 13:43:36 -08003549 checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -07003550 checkOutputForStrategy(STRATEGY_MEDIA);
3551 checkOutputForStrategy(STRATEGY_DTMF);
Eric Laurent223fd5c2014-11-11 13:43:36 -08003552 checkOutputForStrategy(STRATEGY_REROUTING);
Eric Laurente552edb2014-03-10 17:42:56 -07003553}
3554
Eric Laurente0720872014-03-11 09:30:41 -07003555void AudioPolicyManager::checkA2dpSuspend()
Eric Laurente552edb2014-03-10 17:42:56 -07003556{
François Gaffie53615e22015-03-19 09:24:12 +01003557 audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
Eric Laurente552edb2014-03-10 17:42:56 -07003558 if (a2dpOutput == 0) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003559 mA2dpSuspended = false;
Eric Laurente552edb2014-03-10 17:42:56 -07003560 return;
3561 }
3562
Eric Laurent3a4311c2014-03-17 12:00:47 -07003563 bool isScoConnected =
Eric Laurentddbc6652014-11-13 15:13:44 -08003564 ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
3565 ~AUDIO_DEVICE_BIT_IN) != 0) ||
3566 ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07003567 // suspend A2DP output if:
3568 // (NOT already suspended) &&
3569 // ((SCO device is connected &&
3570 // (forced usage for communication || for record is SCO))) ||
3571 // (phone state is ringing || in call)
3572 //
3573 // restore A2DP output if:
3574 // (Already suspended) &&
3575 // ((SCO device is NOT connected ||
3576 // (forced usage NOT for communication && NOT for record is SCO))) &&
3577 // (phone state is NOT ringing && NOT in call)
3578 //
3579 if (mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003580 if ((!isScoConnected ||
François Gaffie2110e042015-03-24 08:41:51 +01003581 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) != AUDIO_POLICY_FORCE_BT_SCO) &&
3582 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) != AUDIO_POLICY_FORCE_BT_SCO))) &&
3583 ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
3584 (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003585
3586 mpClientInterface->restoreOutput(a2dpOutput);
3587 mA2dpSuspended = false;
3588 }
3589 } else {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003590 if ((isScoConnected &&
François Gaffie2110e042015-03-24 08:41:51 +01003591 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) ||
3592 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO))) ||
3593 ((mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
3594 (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003595
3596 mpClientInterface->suspendOutput(a2dpOutput);
3597 mA2dpSuspended = true;
3598 }
3599 }
3600}
3601
Eric Laurent1c333e22014-05-20 10:48:17 -07003602audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07003603{
3604 audio_devices_t device = AUDIO_DEVICE_NONE;
3605
Eric Laurent1f2f2232014-06-02 12:01:23 -07003606 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07003607
3608 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3609 if (index >= 0) {
3610 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3611 if (patchDesc->mUid != mUidCached) {
3612 ALOGV("getNewOutputDevice() device %08x forced by patch %d",
3613 outputDesc->device(), outputDesc->mPatchHandle);
3614 return outputDesc->device();
3615 }
3616 }
3617
Eric Laurente552edb2014-03-10 17:42:56 -07003618 // check the following by order of priority to request a routing change if necessary:
Jon Eklund966095e2014-09-09 15:39:49 -05003619 // 1: the strategy enforced audible is active and enforced on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003620 // use device for strategy enforced audible
3621 // 2: we are in call or the strategy phone is active on the output:
3622 // use device for strategy phone
Jon Eklund966095e2014-09-09 15:39:49 -05003623 // 3: the strategy for enforced audible is active but not enforced on the output:
3624 // use the device for strategy enforced audible
3625 // 4: the strategy sonification is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003626 // use device for strategy sonification
Jon Eklund966095e2014-09-09 15:39:49 -05003627 // 5: the strategy "respectful" sonification is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003628 // use device for strategy "respectful" sonification
Eric Laurent223fd5c2014-11-11 13:43:36 -08003629 // 6: the strategy accessibility is active on the output:
3630 // use device for strategy accessibility
3631 // 7: the strategy media is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003632 // use device for strategy media
Eric Laurent223fd5c2014-11-11 13:43:36 -08003633 // 8: the strategy DTMF is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003634 // use device for strategy DTMF
Eric Laurent223fd5c2014-11-11 13:43:36 -08003635 // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003636 // use device for strategy t-t-s
François Gaffiead3183e2015-03-18 16:55:35 +01003637 if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01003638 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
Eric Laurente552edb2014-03-10 17:42:56 -07003639 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
3640 } else if (isInCall() ||
François Gaffiead3183e2015-03-18 16:55:35 +01003641 isStrategyActive(outputDesc, STRATEGY_PHONE)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003642 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003643 } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
Jon Eklund966095e2014-09-09 15:39:49 -05003644 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003645 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003646 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003647 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003648 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003649 } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08003650 device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003651 } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003652 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003653 } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003654 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003655 } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003656 device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003657 } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08003658 device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
Eric Laurente552edb2014-03-10 17:42:56 -07003659 }
3660
Eric Laurent1c333e22014-05-20 10:48:17 -07003661 ALOGV("getNewOutputDevice() selected device %x", device);
3662 return device;
3663}
3664
3665audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
3666{
Eric Laurent1f2f2232014-06-02 12:01:23 -07003667 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07003668
3669 ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
3670 if (index >= 0) {
3671 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3672 if (patchDesc->mUid != mUidCached) {
3673 ALOGV("getNewInputDevice() device %08x forced by patch %d",
3674 inputDesc->mDevice, inputDesc->mPatchHandle);
3675 return inputDesc->mDevice;
3676 }
3677 }
3678
Eric Laurentc73ca6e2014-12-12 14:34:22 -08003679 audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource);
Eric Laurent1c333e22014-05-20 10:48:17 -07003680
3681 ALOGV("getNewInputDevice() selected device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07003682 return device;
3683}
3684
Eric Laurente0720872014-03-11 09:30:41 -07003685uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003686 return (uint32_t)getStrategy(stream);
3687}
3688
Eric Laurente0720872014-03-11 09:30:41 -07003689audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003690 // By checking the range of stream before calling getStrategy, we avoid
3691 // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
3692 // and then return STRATEGY_MEDIA, but we want to return the empty set.
Eric Laurent223fd5c2014-11-11 13:43:36 -08003693 if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003694 return AUDIO_DEVICE_NONE;
3695 }
3696 audio_devices_t devices;
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -08003697 routing_strategy strategy = getStrategy(stream);
Eric Laurent6a94d692014-05-20 11:18:06 -07003698 devices = getDeviceForStrategy(strategy, true /*fromCache*/);
3699 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
3700 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003701 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
François Gaffiead3183e2015-03-18 16:55:35 +01003702 if (isStrategyActive(outputDesc, strategy)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003703 devices = outputDesc->device();
3704 break;
3705 }
Eric Laurente552edb2014-03-10 17:42:56 -07003706 }
Jon Eklund11c9fb12014-06-23 14:47:03 -05003707
3708 /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
3709 and doesn't really need to.*/
3710 if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
3711 devices |= AUDIO_DEVICE_OUT_SPEAKER;
3712 devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
3713 }
3714
Eric Laurente552edb2014-03-10 17:42:56 -07003715 return devices;
3716}
3717
François Gaffie2110e042015-03-24 08:41:51 +01003718routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
3719{
Eric Laurent223fd5c2014-11-11 13:43:36 -08003720 ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
François Gaffie2110e042015-03-24 08:41:51 +01003721 return mEngine->getStrategyForStream(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07003722}
3723
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07003724uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
3725 // flags to strategy mapping
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003726 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
3727 return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
3728 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07003729 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
3730 return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
3731 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07003732 // usage to strategy mapping
François Gaffie2110e042015-03-24 08:41:51 +01003733 return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07003734}
3735
Eric Laurente0720872014-03-11 09:30:41 -07003736void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003737 switch(stream) {
Eric Laurent3b73df72014-03-11 09:06:29 -07003738 case AUDIO_STREAM_MUSIC:
Eric Laurente552edb2014-03-10 17:42:56 -07003739 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
3740 updateDevicesAndOutputs();
3741 break;
3742 default:
3743 break;
3744 }
3745}
3746
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003747uint32_t AudioPolicyManager::handleEventForBeacon(int event) {
3748 switch(event) {
3749 case STARTING_OUTPUT:
3750 mBeaconMuteRefCount++;
3751 break;
3752 case STOPPING_OUTPUT:
3753 if (mBeaconMuteRefCount > 0) {
3754 mBeaconMuteRefCount--;
3755 }
3756 break;
3757 case STARTING_BEACON:
3758 mBeaconPlayingRefCount++;
3759 break;
3760 case STOPPING_BEACON:
3761 if (mBeaconPlayingRefCount > 0) {
3762 mBeaconPlayingRefCount--;
3763 }
3764 break;
3765 }
3766
3767 if (mBeaconMuteRefCount > 0) {
3768 // any playback causes beacon to be muted
3769 return setBeaconMute(true);
3770 } else {
3771 // no other playback: unmute when beacon starts playing, mute when it stops
3772 return setBeaconMute(mBeaconPlayingRefCount == 0);
3773 }
3774}
3775
3776uint32_t AudioPolicyManager::setBeaconMute(bool mute) {
3777 ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
3778 mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
3779 // keep track of muted state to avoid repeating mute/unmute operations
3780 if (mBeaconMuted != mute) {
3781 // mute/unmute AUDIO_STREAM_TTS on all outputs
3782 ALOGV("\t muting %d", mute);
3783 uint32_t maxLatency = 0;
3784 for (size_t i = 0; i < mOutputs.size(); i++) {
3785 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
3786 setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
3787 desc->mIoHandle,
3788 0 /*delay*/, AUDIO_DEVICE_NONE);
3789 const uint32_t latency = desc->latency() * 2;
3790 if (latency > maxLatency) {
3791 maxLatency = latency;
3792 }
3793 }
3794 mBeaconMuted = mute;
3795 return maxLatency;
3796 }
3797 return 0;
3798}
3799
Eric Laurente0720872014-03-11 09:30:41 -07003800audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
François Gaffie53615e22015-03-19 09:24:12 +01003801 bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07003802{
Paul McLeanaa981192015-03-21 09:55:15 -07003803 // Routing
3804 // see if we have an explicit route
3805 // scan the whole RouteMap, for each entry, convert the stream type to a strategy
3806 // (getStrategy(stream)).
3807 // if the strategy from the stream type in the RouteMap is the same as the argument above,
3808 // and activity count is non-zero
3809 // the device = the device from the descriptor in the RouteMap, and exit.
3810 for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
3811 sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
3812 routing_strategy strat = getStrategy(route->mStreamType);
3813 if (strat == strategy && route->mDeviceDescriptor != 0 /*&& route->mActivityCount != 0*/) {
3814 return route->mDeviceDescriptor->type();
3815 }
3816 }
3817
Eric Laurente552edb2014-03-10 17:42:56 -07003818 if (fromCache) {
3819 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
3820 strategy, mDeviceForStrategy[strategy]);
3821 return mDeviceForStrategy[strategy];
3822 }
François Gaffie2110e042015-03-24 08:41:51 +01003823 return mEngine->getDeviceForStrategy(strategy);
Eric Laurente552edb2014-03-10 17:42:56 -07003824}
3825
Eric Laurente0720872014-03-11 09:30:41 -07003826void AudioPolicyManager::updateDevicesAndOutputs()
Eric Laurente552edb2014-03-10 17:42:56 -07003827{
3828 for (int i = 0; i < NUM_STRATEGIES; i++) {
3829 mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
3830 }
3831 mPreviousOutputs = mOutputs;
3832}
3833
Eric Laurent1f2f2232014-06-02 12:01:23 -07003834uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07003835 audio_devices_t prevDevice,
3836 uint32_t delayMs)
3837{
3838 // mute/unmute strategies using an incompatible device combination
3839 // if muting, wait for the audio in pcm buffer to be drained before proceeding
3840 // if unmuting, unmute only after the specified delay
3841 if (outputDesc->isDuplicated()) {
3842 return 0;
3843 }
3844
3845 uint32_t muteWaitMs = 0;
3846 audio_devices_t device = outputDesc->device();
Eric Laurent3b73df72014-03-11 09:06:29 -07003847 bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
Eric Laurente552edb2014-03-10 17:42:56 -07003848
3849 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
3850 audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
Eric Laurent31551f82014-10-10 18:21:56 -07003851 curDevice = curDevice & outputDesc->mProfile->mSupportedDevices.types();
Eric Laurente552edb2014-03-10 17:42:56 -07003852 bool mute = shouldMute && (curDevice & device) && (curDevice != device);
3853 bool doMute = false;
3854
3855 if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
3856 doMute = true;
3857 outputDesc->mStrategyMutedByDevice[i] = true;
3858 } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
3859 doMute = true;
3860 outputDesc->mStrategyMutedByDevice[i] = false;
3861 }
Eric Laurent99401132014-05-07 19:48:15 -07003862 if (doMute) {
Eric Laurente552edb2014-03-10 17:42:56 -07003863 for (size_t j = 0; j < mOutputs.size(); j++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003864 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
Eric Laurente552edb2014-03-10 17:42:56 -07003865 // skip output if it does not share any device with current output
3866 if ((desc->supportedDevices() & outputDesc->supportedDevices())
3867 == AUDIO_DEVICE_NONE) {
3868 continue;
3869 }
3870 audio_io_handle_t curOutput = mOutputs.keyAt(j);
3871 ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
3872 mute ? "muting" : "unmuting", i, curDevice, curOutput);
3873 setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
François Gaffiead3183e2015-03-18 16:55:35 +01003874 if (isStrategyActive(desc, (routing_strategy)i)) {
Eric Laurent99401132014-05-07 19:48:15 -07003875 if (mute) {
3876 // FIXME: should not need to double latency if volume could be applied
3877 // immediately by the audioflinger mixer. We must account for the delay
3878 // between now and the next time the audioflinger thread for this output
3879 // will process a buffer (which corresponds to one buffer size,
3880 // usually 1/2 or 1/4 of the latency).
3881 if (muteWaitMs < desc->latency() * 2) {
3882 muteWaitMs = desc->latency() * 2;
Eric Laurente552edb2014-03-10 17:42:56 -07003883 }
3884 }
3885 }
3886 }
3887 }
3888 }
3889
Eric Laurent99401132014-05-07 19:48:15 -07003890 // temporary mute output if device selection changes to avoid volume bursts due to
3891 // different per device volumes
3892 if (outputDesc->isActive() && (device != prevDevice)) {
3893 if (muteWaitMs < outputDesc->latency() * 2) {
3894 muteWaitMs = outputDesc->latency() * 2;
3895 }
3896 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
François Gaffiead3183e2015-03-18 16:55:35 +01003897 if (isStrategyActive(outputDesc, (routing_strategy)i)) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003898 setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle);
Eric Laurent99401132014-05-07 19:48:15 -07003899 // do tempMute unmute after twice the mute wait time
Eric Laurent1c333e22014-05-20 10:48:17 -07003900 setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle,
Eric Laurent99401132014-05-07 19:48:15 -07003901 muteWaitMs *2, device);
3902 }
3903 }
3904 }
3905
Eric Laurente552edb2014-03-10 17:42:56 -07003906 // wait for the PCM output buffers to empty before proceeding with the rest of the command
3907 if (muteWaitMs > delayMs) {
3908 muteWaitMs -= delayMs;
3909 usleep(muteWaitMs * 1000);
3910 return muteWaitMs;
3911 }
3912 return 0;
3913}
3914
Eric Laurente0720872014-03-11 09:30:41 -07003915uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
Eric Laurente552edb2014-03-10 17:42:56 -07003916 audio_devices_t device,
3917 bool force,
Eric Laurent6a94d692014-05-20 11:18:06 -07003918 int delayMs,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003919 audio_patch_handle_t *patchHandle,
3920 const char* address)
Eric Laurente552edb2014-03-10 17:42:56 -07003921{
3922 ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003923 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003924 AudioParameter param;
3925 uint32_t muteWaitMs;
3926
3927 if (outputDesc->isDuplicated()) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003928 muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs);
3929 muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07003930 return muteWaitMs;
3931 }
3932 // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
3933 // output profile
Paul McLeanaa981192015-03-21 09:55:15 -07003934 if (device != AUDIO_DEVICE_NONE &&
3935 (device & outputDesc->mProfile->mSupportedDevices.types()) == 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07003936 return 0;
3937 }
3938
3939 // filter devices according to output selected
Eric Laurent3a4311c2014-03-17 12:00:47 -07003940 device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
Eric Laurente552edb2014-03-10 17:42:56 -07003941
3942 audio_devices_t prevDevice = outputDesc->mDevice;
3943
Paul McLeanaa981192015-03-21 09:55:15 -07003944 ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07003945
3946 if (device != AUDIO_DEVICE_NONE) {
3947 outputDesc->mDevice = device;
3948 }
3949 muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
3950
3951 // Do not change the routing if:
Eric Laurentb80a2a82014-10-27 16:07:59 -07003952 // the requested device is AUDIO_DEVICE_NONE
3953 // OR the requested device is the same as current device
3954 // AND force is not specified
3955 // AND the output is connected by a valid audio patch.
Eric Laurente552edb2014-03-10 17:42:56 -07003956 // Doing this check here allows the caller to call setOutputDevice() without conditions
Paul McLeanaa981192015-03-21 09:55:15 -07003957 if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
3958 !force &&
3959 outputDesc->mPatchHandle != 0) {
3960 ALOGV("setOutputDevice() setting same device 0x%04x or null device for output %d",
Eric Laurentb80a2a82014-10-27 16:07:59 -07003961 device, output);
Eric Laurente552edb2014-03-10 17:42:56 -07003962 return muteWaitMs;
3963 }
3964
3965 ALOGV("setOutputDevice() changing device");
Eric Laurent1c333e22014-05-20 10:48:17 -07003966
Eric Laurente552edb2014-03-10 17:42:56 -07003967 // do the routing
Eric Laurent1c333e22014-05-20 10:48:17 -07003968 if (device == AUDIO_DEVICE_NONE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003969 resetOutputDevice(output, delayMs, NULL);
Eric Laurent1c333e22014-05-20 10:48:17 -07003970 } else {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003971 DeviceVector deviceList = (address == NULL) ?
3972 mAvailableOutputDevices.getDevicesFromType(device)
3973 : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
Eric Laurent1c333e22014-05-20 10:48:17 -07003974 if (!deviceList.isEmpty()) {
3975 struct audio_patch patch;
3976 outputDesc->toAudioPortConfig(&patch.sources[0]);
3977 patch.num_sources = 1;
3978 patch.num_sinks = 0;
3979 for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
3980 deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
Eric Laurent1c333e22014-05-20 10:48:17 -07003981 patch.num_sinks++;
3982 }
Eric Laurent6a94d692014-05-20 11:18:06 -07003983 ssize_t index;
3984 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
3985 index = mAudioPatches.indexOfKey(*patchHandle);
3986 } else {
3987 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3988 }
3989 sp< AudioPatch> patchDesc;
3990 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3991 if (index >= 0) {
3992 patchDesc = mAudioPatches.valueAt(index);
3993 afPatchHandle = patchDesc->mAfPatchHandle;
3994 }
3995
Eric Laurent1c333e22014-05-20 10:48:17 -07003996 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07003997 &afPatchHandle,
3998 delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07003999 ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
4000 "num_sources %d num_sinks %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004001 status, afPatchHandle, patch.num_sources, patch.num_sinks);
Eric Laurent1c333e22014-05-20 10:48:17 -07004002 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004003 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01004004 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07004005 addAudioPatch(patchDesc->mHandle, patchDesc);
4006 } else {
4007 patchDesc->mPatch = patch;
4008 }
4009 patchDesc->mAfPatchHandle = afPatchHandle;
4010 patchDesc->mUid = mUidCached;
4011 if (patchHandle) {
4012 *patchHandle = patchDesc->mHandle;
4013 }
4014 outputDesc->mPatchHandle = patchDesc->mHandle;
4015 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004016 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004017 }
4018 }
bryant_liuf5e7e792014-08-19 20:07:05 +08004019
4020 // inform all input as well
4021 for (size_t i = 0; i < mInputs.size(); i++) {
4022 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
François Gaffie53615e22015-03-19 09:24:12 +01004023 if (!is_virtual_input_device(inputDescriptor->mDevice)) {
bryant_liuf5e7e792014-08-19 20:07:05 +08004024 AudioParameter inputCmd = AudioParameter();
4025 ALOGV("%s: inform input %d of device:%d", __func__,
4026 inputDescriptor->mIoHandle, device);
4027 inputCmd.addInt(String8(AudioParameter::keyRouting),device);
4028 mpClientInterface->setParameters(inputDescriptor->mIoHandle,
4029 inputCmd.toString(),
4030 delayMs);
4031 }
4032 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004033 }
Eric Laurente552edb2014-03-10 17:42:56 -07004034
4035 // update stream volumes according to new device
4036 applyStreamVolumes(output, device, delayMs);
4037
4038 return muteWaitMs;
4039}
4040
Eric Laurent1c333e22014-05-20 10:48:17 -07004041status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output,
Eric Laurent6a94d692014-05-20 11:18:06 -07004042 int delayMs,
4043 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004044{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004045 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07004046 ssize_t index;
4047 if (patchHandle) {
4048 index = mAudioPatches.indexOfKey(*patchHandle);
4049 } else {
4050 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
4051 }
4052 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004053 return INVALID_OPERATION;
4054 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004055 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4056 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07004057 ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
4058 outputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004059 removeAudioPatch(patchDesc->mHandle);
4060 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004061 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004062 return status;
4063}
4064
4065status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
4066 audio_devices_t device,
Eric Laurent6a94d692014-05-20 11:18:06 -07004067 bool force,
4068 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004069{
4070 status_t status = NO_ERROR;
4071
Eric Laurent1f2f2232014-06-02 12:01:23 -07004072 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07004073 if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
4074 inputDesc->mDevice = device;
4075
4076 DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
4077 if (!deviceList.isEmpty()) {
4078 struct audio_patch patch;
4079 inputDesc->toAudioPortConfig(&patch.sinks[0]);
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004080 // AUDIO_SOURCE_HOTWORD is for internal use only:
4081 // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07004082 if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
4083 !inputDesc->mIsSoundTrigger) {
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004084 patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
4085 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004086 patch.num_sinks = 1;
4087 //only one input device for now
4088 deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
Eric Laurent1c333e22014-05-20 10:48:17 -07004089 patch.num_sources = 1;
Eric Laurent6a94d692014-05-20 11:18:06 -07004090 ssize_t index;
4091 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
4092 index = mAudioPatches.indexOfKey(*patchHandle);
4093 } else {
4094 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4095 }
4096 sp< AudioPatch> patchDesc;
4097 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
4098 if (index >= 0) {
4099 patchDesc = mAudioPatches.valueAt(index);
4100 afPatchHandle = patchDesc->mAfPatchHandle;
4101 }
4102
Eric Laurent1c333e22014-05-20 10:48:17 -07004103 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07004104 &afPatchHandle,
Eric Laurent1c333e22014-05-20 10:48:17 -07004105 0);
4106 ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004107 status, afPatchHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -07004108 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004109 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01004110 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07004111 addAudioPatch(patchDesc->mHandle, patchDesc);
4112 } else {
4113 patchDesc->mPatch = patch;
4114 }
4115 patchDesc->mAfPatchHandle = afPatchHandle;
4116 patchDesc->mUid = mUidCached;
4117 if (patchHandle) {
4118 *patchHandle = patchDesc->mHandle;
4119 }
4120 inputDesc->mPatchHandle = patchDesc->mHandle;
4121 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004122 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004123 }
4124 }
4125 }
4126 return status;
4127}
4128
Eric Laurent6a94d692014-05-20 11:18:06 -07004129status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
4130 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004131{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004132 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07004133 ssize_t index;
4134 if (patchHandle) {
4135 index = mAudioPatches.indexOfKey(*patchHandle);
4136 } else {
4137 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4138 }
4139 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004140 return INVALID_OPERATION;
4141 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004142 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4143 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent1c333e22014-05-20 10:48:17 -07004144 ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
4145 inputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004146 removeAudioPatch(patchDesc->mHandle);
4147 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004148 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004149 return status;
4150}
4151
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -08004152sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +01004153 String8 address,
4154 uint32_t& samplingRate,
4155 audio_format_t format,
4156 audio_channel_mask_t channelMask,
4157 audio_input_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07004158{
4159 // Choose an input profile based on the requested capture parameters: select the first available
4160 // profile supporting all requested parameters.
4161
4162 for (size_t i = 0; i < mHwModules.size(); i++)
4163 {
4164 if (mHwModules[i]->mHandle == 0) {
4165 continue;
4166 }
4167 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
4168 {
Eric Laurent1c333e22014-05-20 10:48:17 -07004169 sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07004170 // profile->log();
Eric Laurent275e8e92014-11-30 15:14:47 -08004171 if (profile->isCompatibleProfile(device, address, samplingRate,
Glenn Kastencbd48022014-07-24 13:46:44 -07004172 &samplingRate /*updatedSamplingRate*/,
4173 format, channelMask, (audio_output_flags_t) flags)) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004174
Eric Laurente552edb2014-03-10 17:42:56 -07004175 return profile;
4176 }
4177 }
4178 }
4179 return NULL;
4180}
4181
Eric Laurentc73ca6e2014-12-12 14:34:22 -08004182
4183audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
François Gaffie53615e22015-03-19 09:24:12 +01004184 AudioMix **policyMix)
Eric Laurente552edb2014-03-10 17:42:56 -07004185{
François Gaffie036e1e92015-03-19 10:16:24 +01004186 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
4187 audio_devices_t selectedDeviceFromMix =
4188 mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08004189
François Gaffie036e1e92015-03-19 10:16:24 +01004190 if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
4191 return selectedDeviceFromMix;
Eric Laurent275e8e92014-11-30 15:14:47 -08004192 }
Eric Laurentc73ca6e2014-12-12 14:34:22 -08004193 return getDeviceForInputSource(inputSource);
4194}
4195
4196audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
4197{
François Gaffie2110e042015-03-24 08:41:51 +01004198 return mEngine->getDeviceForInputSource(inputSource);
Eric Laurente552edb2014-03-10 17:42:56 -07004199}
4200
Eric Laurente0720872014-03-11 09:30:41 -07004201float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01004202 int index,
4203 audio_io_handle_t output,
4204 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004205{
4206 float volume = 1.0;
Eric Laurent1f2f2232014-06-02 12:01:23 -07004207 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004208
4209 if (device == AUDIO_DEVICE_NONE) {
4210 device = outputDesc->device();
4211 }
François Gaffie2110e042015-03-24 08:41:51 +01004212 volume = mEngine->volIndexToAmpl(Volume::getDeviceCategory(device), stream, index);
Eric Laurente552edb2014-03-10 17:42:56 -07004213
4214 // if a headset is connected, apply the following rules to ring tones and notifications
4215 // to avoid sound level bursts in user's ears:
4216 // - always attenuate ring tones and notifications volume by 6dB
4217 // - if music is playing, always limit the volume to current music volume,
4218 // with a minimum threshold at -36dB so that notification is always perceived.
Eric Laurent3b73df72014-03-11 09:06:29 -07004219 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004220 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
4221 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
4222 AUDIO_DEVICE_OUT_WIRED_HEADSET |
4223 AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
4224 ((stream_strategy == STRATEGY_SONIFICATION)
4225 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
Eric Laurent3b73df72014-03-11 09:06:29 -07004226 || (stream == AUDIO_STREAM_SYSTEM)
Eric Laurente552edb2014-03-10 17:42:56 -07004227 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01004228 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
4229 mStreams.canBeMuted(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004230 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
4231 // when the phone is ringing we must consider that music could have been paused just before
4232 // by the music application and behave as if music was active if the last music track was
4233 // just stopped
Eric Laurent3b73df72014-03-11 09:06:29 -07004234 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
Eric Laurente552edb2014-03-10 17:42:56 -07004235 mLimitRingtoneVolume) {
4236 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
Eric Laurent3b73df72014-03-11 09:06:29 -07004237 float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
4238 mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
Eric Laurente552edb2014-03-10 17:42:56 -07004239 output,
4240 musicDevice);
4241 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
4242 musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
4243 if (volume > minVol) {
4244 volume = minVol;
4245 ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
4246 }
4247 }
4248 }
4249
4250 return volume;
4251}
4252
Eric Laurente0720872014-03-11 09:30:41 -07004253status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01004254 int index,
4255 audio_io_handle_t output,
4256 audio_devices_t device,
4257 int delayMs,
4258 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07004259{
4260
4261 // do not change actual stream volume if the stream is muted
4262 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
4263 ALOGVV("checkAndSetVolume() stream %d muted count %d",
4264 stream, mOutputs.valueFor(output)->mMuteCount[stream]);
4265 return NO_ERROR;
4266 }
François Gaffie2110e042015-03-24 08:41:51 +01004267 audio_policy_forced_cfg_t forceUseForComm =
4268 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
Eric Laurente552edb2014-03-10 17:42:56 -07004269 // do not change in call volume if bluetooth is connected and vice versa
François Gaffie2110e042015-03-24 08:41:51 +01004270 if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
4271 (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004272 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
François Gaffie2110e042015-03-24 08:41:51 +01004273 stream, forceUseForComm);
Eric Laurente552edb2014-03-10 17:42:56 -07004274 return INVALID_OPERATION;
4275 }
4276
4277 float volume = computeVolume(stream, index, output, device);
Eric Laurent275e8e92014-11-30 15:14:47 -08004278 // unit gain if rerouting to external policy
4279 if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
4280 ssize_t index = mOutputs.indexOfKey(output);
4281 if (index >= 0) {
4282 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurentc722f302014-12-10 11:21:49 -08004283 if (outputDesc->mPolicyMix != NULL) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004284 ALOGV("max gain when rerouting for output=%d", output);
4285 volume = 1.0f;
4286 }
4287 }
4288
4289 }
Eric Laurente552edb2014-03-10 17:42:56 -07004290 // We actually change the volume if:
4291 // - the float value returned by computeVolume() changed
4292 // - the force flag is set
4293 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
4294 force) {
4295 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
4296 ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
4297 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
4298 // enabled
Eric Laurent3b73df72014-03-11 09:06:29 -07004299 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
4300 mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004301 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004302 mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004303 }
4304
Eric Laurent3b73df72014-03-11 09:06:29 -07004305 if (stream == AUDIO_STREAM_VOICE_CALL ||
4306 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
Eric Laurente552edb2014-03-10 17:42:56 -07004307 float voiceVolume;
4308 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
Eric Laurent3b73df72014-03-11 09:06:29 -07004309 if (stream == AUDIO_STREAM_VOICE_CALL) {
François Gaffiedfd74092015-03-19 12:10:59 +01004310 voiceVolume = (float)index/(float)mStreams[stream].getVolumeIndexMax();
Eric Laurente552edb2014-03-10 17:42:56 -07004311 } else {
4312 voiceVolume = 1.0;
4313 }
4314
4315 if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
4316 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
4317 mLastVoiceVolume = voiceVolume;
4318 }
4319 }
4320
4321 return NO_ERROR;
4322}
4323
Eric Laurente0720872014-03-11 09:30:41 -07004324void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
François Gaffie53615e22015-03-19 09:24:12 +01004325 audio_devices_t device,
4326 int delayMs,
4327 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07004328{
4329 ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
4330
Eric Laurent3b73df72014-03-11 09:06:29 -07004331 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004332 if (stream == AUDIO_STREAM_PATCH) {
4333 continue;
4334 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004335 checkAndSetVolume((audio_stream_type_t)stream,
Eric Laurente552edb2014-03-10 17:42:56 -07004336 mStreams[stream].getVolumeIndex(device),
4337 output,
4338 device,
4339 delayMs,
4340 force);
4341 }
4342}
4343
Eric Laurente0720872014-03-11 09:30:41 -07004344void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
François Gaffie53615e22015-03-19 09:24:12 +01004345 bool on,
4346 audio_io_handle_t output,
4347 int delayMs,
4348 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004349{
4350 ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
Eric Laurent3b73df72014-03-11 09:06:29 -07004351 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004352 if (stream == AUDIO_STREAM_PATCH) {
4353 continue;
4354 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004355 if (getStrategy((audio_stream_type_t)stream) == strategy) {
4356 setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
Eric Laurente552edb2014-03-10 17:42:56 -07004357 }
4358 }
4359}
4360
Eric Laurente0720872014-03-11 09:30:41 -07004361void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01004362 bool on,
4363 audio_io_handle_t output,
4364 int delayMs,
4365 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004366{
François Gaffiedfd74092015-03-19 12:10:59 +01004367 const StreamDescriptor &streamDesc = mStreams[stream];
Eric Laurent1f2f2232014-06-02 12:01:23 -07004368 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004369 if (device == AUDIO_DEVICE_NONE) {
4370 device = outputDesc->device();
4371 }
4372
4373 ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
4374 stream, on, output, outputDesc->mMuteCount[stream], device);
4375
4376 if (on) {
4377 if (outputDesc->mMuteCount[stream] == 0) {
François Gaffiedfd74092015-03-19 12:10:59 +01004378 if (streamDesc.canBeMuted() &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004379 ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
François Gaffie2110e042015-03-24 08:41:51 +01004380 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07004381 checkAndSetVolume(stream, 0, output, device, delayMs);
4382 }
4383 }
4384 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
4385 outputDesc->mMuteCount[stream]++;
4386 } else {
4387 if (outputDesc->mMuteCount[stream] == 0) {
4388 ALOGV("setStreamMute() unmuting non muted stream!");
4389 return;
4390 }
4391 if (--outputDesc->mMuteCount[stream] == 0) {
4392 checkAndSetVolume(stream,
4393 streamDesc.getVolumeIndex(device),
4394 output,
4395 device,
4396 delayMs);
4397 }
4398 }
4399}
4400
Eric Laurente0720872014-03-11 09:30:41 -07004401void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07004402 bool starting, bool stateChange)
Eric Laurente552edb2014-03-10 17:42:56 -07004403{
4404 // if the stream pertains to sonification strategy and we are in call we must
4405 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
4406 // in the device used for phone strategy and play the tone if the selected device does not
4407 // interfere with the device used for phone strategy
4408 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
4409 // many times as there are active tracks on the output
Eric Laurent3b73df72014-03-11 09:06:29 -07004410 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004411 if ((stream_strategy == STRATEGY_SONIFICATION) ||
4412 ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004413 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07004414 ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
4415 stream, starting, outputDesc->mDevice, stateChange);
4416 if (outputDesc->mRefCount[stream]) {
4417 int muteCount = 1;
4418 if (stateChange) {
4419 muteCount = outputDesc->mRefCount[stream];
4420 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004421 if (audio_is_low_visibility(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004422 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
4423 for (int i = 0; i < muteCount; i++) {
4424 setStreamMute(stream, starting, mPrimaryOutput);
4425 }
4426 } else {
4427 ALOGV("handleIncallSonification() high visibility");
4428 if (outputDesc->device() &
4429 getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
4430 ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
4431 for (int i = 0; i < muteCount; i++) {
4432 setStreamMute(stream, starting, mPrimaryOutput);
4433 }
4434 }
4435 if (starting) {
Eric Laurent3b73df72014-03-11 09:06:29 -07004436 mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
4437 AUDIO_STREAM_VOICE_CALL);
Eric Laurente552edb2014-03-10 17:42:56 -07004438 } else {
4439 mpClientInterface->stopTone();
4440 }
4441 }
4442 }
4443 }
4444}
4445
Paul McLeanaa981192015-03-21 09:55:15 -07004446// --- SessionRoute class implementation
4447void AudioPolicyManager::SessionRoute::log(const char* prefix) {
4448 ALOGI("%s[SessionRoute strm:0x%X, sess:0x%X, dev:0x%X refs:%d act:%d",
4449 prefix, mStreamType, mSession,
4450 mDeviceDescriptor != 0 ? mDeviceDescriptor->type() : AUDIO_DEVICE_NONE,
4451 mRefCount, mActivityCount);
4452}
4453
4454// --- SessionRouteMap class implementation
4455bool AudioPolicyManager::SessionRouteMap::hasRoute(audio_session_t session)
4456{
4457 return indexOfKey(session) >= 0 && valueFor(session)->mDeviceDescriptor != 0;
4458}
4459
4460void AudioPolicyManager::SessionRouteMap::addRoute(audio_session_t session,
4461 audio_stream_type_t streamType,
4462 sp<DeviceDescriptor> deviceDescriptor)
4463{
4464 sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
4465 if (route != NULL) {
4466 route->mRefCount++;
4467 route->mDeviceDescriptor = deviceDescriptor;
4468 } else {
4469 route = new AudioPolicyManager::SessionRoute(session, streamType, deviceDescriptor);
4470 route->mRefCount++;
4471 add(session, route);
4472 }
4473}
4474
4475void AudioPolicyManager::SessionRouteMap::removeRoute(audio_session_t session)
4476{
4477 sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
4478 if (route != 0) {
4479 ALOG_ASSERT(route->mRefCount > 0);
4480 --route->mRefCount;
4481 if (route->mRefCount <= 0) {
4482 removeItem(session);
4483 }
4484 }
4485}
4486
4487int AudioPolicyManager::SessionRouteMap::incRouteActivity(audio_session_t session)
4488{
4489 sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
4490 return route != 0 ? ++(route->mActivityCount) : -1;
4491}
4492
4493int AudioPolicyManager::SessionRouteMap::decRouteActivity(audio_session_t session)
4494{
4495 sp<SessionRoute> route = indexOfKey(session) >= 0 ? valueFor(session) : 0;
4496 if (route != 0 && route->mActivityCount > 0) {
4497 return --(route->mActivityCount);
4498 } else {
4499 return -1;
4500 }
4501}
4502
4503void AudioPolicyManager::SessionRouteMap::log(const char* caption) {
4504 ALOGI("%s ----", caption);
4505 for(size_t index = 0; index < size(); index++) {
4506 valueAt(index)->log(" ");
4507 }
4508}
4509
Eric Laurente0720872014-03-11 09:30:41 -07004510void AudioPolicyManager::defaultAudioPolicyConfig(void)
Eric Laurente552edb2014-03-10 17:42:56 -07004511{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004512 sp<HwModule> module;
Eric Laurent1c333e22014-05-20 10:48:17 -07004513 sp<IOProfile> profile;
Paul McLeane743a472015-01-28 11:07:31 -08004514 sp<DeviceDescriptor> defaultInputDevice =
4515 new DeviceDescriptor(String8("builtin-mic"), AUDIO_DEVICE_IN_BUILTIN_MIC);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004516 mAvailableOutputDevices.add(mDefaultOutputDevice);
4517 mAvailableInputDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004518
4519 module = new HwModule("primary");
4520
Eric Laurent1afeecb2014-05-14 08:52:28 -07004521 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module);
Eric Laurente552edb2014-03-10 17:42:56 -07004522 profile->mSamplingRates.add(44100);
4523 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4524 profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004525 profile->mSupportedDevices.add(mDefaultOutputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004526 profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
4527 module->mOutputProfiles.add(profile);
4528
Eric Laurent1afeecb2014-05-14 08:52:28 -07004529 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module);
Eric Laurente552edb2014-03-10 17:42:56 -07004530 profile->mSamplingRates.add(8000);
4531 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4532 profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004533 profile->mSupportedDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004534 module->mInputProfiles.add(profile);
4535
4536 mHwModules.add(module);
4537}
4538
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004539audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
4540{
4541 // flags to stream type mapping
4542 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
4543 return AUDIO_STREAM_ENFORCED_AUDIBLE;
4544 }
4545 if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
4546 return AUDIO_STREAM_BLUETOOTH_SCO;
4547 }
Jean-Michel Trivi79ad4382015-01-29 10:49:39 -08004548 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4549 return AUDIO_STREAM_TTS;
4550 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004551
4552 // usage to stream type mapping
4553 switch (attr->usage) {
4554 case AUDIO_USAGE_MEDIA:
4555 case AUDIO_USAGE_GAME:
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004556 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
4557 return AUDIO_STREAM_MUSIC;
Eric Laurent223fd5c2014-11-11 13:43:36 -08004558 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
Eric Laurente83b55d2014-11-14 10:06:21 -08004559 if (isStreamActive(AUDIO_STREAM_ALARM)) {
4560 return AUDIO_STREAM_ALARM;
4561 }
4562 if (isStreamActive(AUDIO_STREAM_RING)) {
4563 return AUDIO_STREAM_RING;
4564 }
4565 if (isInCall()) {
4566 return AUDIO_STREAM_VOICE_CALL;
4567 }
Eric Laurent223fd5c2014-11-11 13:43:36 -08004568 return AUDIO_STREAM_ACCESSIBILITY;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004569 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
4570 return AUDIO_STREAM_SYSTEM;
4571 case AUDIO_USAGE_VOICE_COMMUNICATION:
4572 return AUDIO_STREAM_VOICE_CALL;
4573
4574 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
4575 return AUDIO_STREAM_DTMF;
4576
4577 case AUDIO_USAGE_ALARM:
4578 return AUDIO_STREAM_ALARM;
4579 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
4580 return AUDIO_STREAM_RING;
4581
4582 case AUDIO_USAGE_NOTIFICATION:
4583 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
4584 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
4585 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
4586 case AUDIO_USAGE_NOTIFICATION_EVENT:
4587 return AUDIO_STREAM_NOTIFICATION;
4588
4589 case AUDIO_USAGE_UNKNOWN:
4590 default:
4591 return AUDIO_STREAM_MUSIC;
4592 }
4593}
Eric Laurente83b55d2014-11-14 10:06:21 -08004594
François Gaffie53615e22015-03-19 09:24:12 +01004595bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
4596{
Eric Laurente83b55d2014-11-14 10:06:21 -08004597 // has flags that map to a strategy?
4598 if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
4599 return true;
4600 }
4601
4602 // has known usage?
4603 switch (paa->usage) {
4604 case AUDIO_USAGE_UNKNOWN:
4605 case AUDIO_USAGE_MEDIA:
4606 case AUDIO_USAGE_VOICE_COMMUNICATION:
4607 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
4608 case AUDIO_USAGE_ALARM:
4609 case AUDIO_USAGE_NOTIFICATION:
4610 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
4611 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
4612 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
4613 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
4614 case AUDIO_USAGE_NOTIFICATION_EVENT:
4615 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
4616 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
4617 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
4618 case AUDIO_USAGE_GAME:
Eric Laurent275e8e92014-11-30 15:14:47 -08004619 case AUDIO_USAGE_VIRTUAL_SOURCE:
Eric Laurente83b55d2014-11-14 10:06:21 -08004620 break;
4621 default:
4622 return false;
4623 }
4624 return true;
4625}
4626
François Gaffiead3183e2015-03-18 16:55:35 +01004627bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor> outputDesc,
4628 routing_strategy strategy, uint32_t inPastMs,
4629 nsecs_t sysTime) const
4630{
4631 if ((sysTime == 0) && (inPastMs != 0)) {
4632 sysTime = systemTime();
4633 }
4634 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
4635 if (i == AUDIO_STREAM_PATCH) {
4636 continue;
4637 }
4638 if (((getStrategy((audio_stream_type_t)i) == strategy) ||
4639 (NUM_STRATEGIES == strategy)) &&
4640 outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
4641 return true;
4642 }
4643 }
4644 return false;
4645}
4646
François Gaffie2110e042015-03-24 08:41:51 +01004647audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
4648{
4649 return mEngine->getForceUse(usage);
4650}
4651
4652bool AudioPolicyManager::isInCall()
4653{
4654 return isStateInCall(mEngine->getPhoneState());
4655}
4656
4657bool AudioPolicyManager::isStateInCall(int state)
4658{
4659 return is_state_in_call(state);
4660}
4661
Eric Laurente552edb2014-03-10 17:42:56 -07004662}; // namespace android