blob: d6e3c16bd0aae429e8ac67ff15fdb73c01724e86 [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
François Gaffie44481e72016-04-20 07:49:57 +020058void AudioPolicyManager::broadcastDeviceConnectionState(audio_devices_t device,
59 audio_policy_dev_state_t state,
60 const String8 &device_address)
61{
62 AudioParameter param(device_address);
63 const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
64 AUDIO_PARAMETER_DEVICE_CONNECT : AUDIO_PARAMETER_DEVICE_DISCONNECT);
65 param.addInt(key, device);
66 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
67}
68
Eric Laurentc73ca6e2014-12-12 14:34:22 -080069status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
Eric Laurenta1d525f2015-01-29 13:36:45 -080070 audio_policy_dev_state_t state,
Paul McLeane743a472015-01-28 11:07:31 -080071 const char *device_address,
72 const char *device_name)
Eric Laurentc73ca6e2014-12-12 14:34:22 -080073{
Paul McLeane743a472015-01-28 11:07:31 -080074 ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
75- device, state, device_address, device_name);
Eric Laurente552edb2014-03-10 17:42:56 -070076
77 // connect/disconnect only 1 device at a time
78 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
79
François Gaffie53615e22015-03-19 09:24:12 +010080 sp<DeviceDescriptor> devDesc =
81 mHwModules.getDeviceDescriptor(device, device_address, device_name);
Paul McLeane743a472015-01-28 11:07:31 -080082
Eric Laurente552edb2014-03-10 17:42:56 -070083 // handle output devices
84 if (audio_is_output_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -070085 SortedVector <audio_io_handle_t> outputs;
86
Eric Laurent3a4311c2014-03-17 12:00:47 -070087 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
88
Eric Laurente552edb2014-03-10 17:42:56 -070089 // save a copy of the opened output descriptors before any output is opened or closed
90 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
91 mPreviousOutputs = mOutputs;
Eric Laurente552edb2014-03-10 17:42:56 -070092 switch (state)
93 {
94 // handle output device connection
Eric Laurent3ae5f312015-02-03 17:12:08 -080095 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -070096 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -070097 ALOGW("setDeviceConnectionState() device already connected: %x", device);
98 return INVALID_OPERATION;
99 }
100 ALOGV("setDeviceConnectionState() connecting device %x", device);
101
Eric Laurente552edb2014-03-10 17:42:56 -0700102 // register new device as available
Eric Laurent3a4311c2014-03-17 12:00:47 -0700103 index = mAvailableOutputDevices.add(devDesc);
104 if (index >= 0) {
François Gaffie53615e22015-03-19 09:24:12 +0100105 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurentcf817a22014-08-04 20:36:31 -0700106 if (module == 0) {
107 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
108 device);
109 mAvailableOutputDevices.remove(devDesc);
110 return INVALID_OPERATION;
111 }
Paul McLeane743a472015-01-28 11:07:31 -0800112 mAvailableOutputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700113 } else {
114 return NO_MEMORY;
Eric Laurente552edb2014-03-10 17:42:56 -0700115 }
116
François Gaffie44481e72016-04-20 07:49:57 +0200117 // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
118 // parameters on newly connected devices (instead of opening the outputs...)
119 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
120
Eric Laurenta1d525f2015-01-29 13:36:45 -0800121 if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700122 mAvailableOutputDevices.remove(devDesc);
François Gaffie44481e72016-04-20 07:49:57 +0200123
124 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
125 devDesc->mAddress);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700126 return INVALID_OPERATION;
127 }
François Gaffie2110e042015-03-24 08:41:51 +0100128 // Propagate device availability to Engine
129 mEngine->setDeviceConnectionState(devDesc, state);
130
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700131 // outputs should never be empty here
132 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
133 "checkOutputsForDevice() returned no outputs but status OK");
134 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
135 outputs.size());
Eric Laurent3ae5f312015-02-03 17:12:08 -0800136
Eric Laurent3ae5f312015-02-03 17:12:08 -0800137 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700138 // handle output device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700139 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700140 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700141 ALOGW("setDeviceConnectionState() device not connected: %x", device);
142 return INVALID_OPERATION;
143 }
144
Paul McLean5c477aa2014-08-20 16:47:57 -0700145 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
146
Paul McLeane743a472015-01-28 11:07:31 -0800147 // Send Disconnect to HALs
François Gaffie44481e72016-04-20 07:49:57 +0200148 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700149
Eric Laurente552edb2014-03-10 17:42:56 -0700150 // remove device from available output devices
Eric Laurent3a4311c2014-03-17 12:00:47 -0700151 mAvailableOutputDevices.remove(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700152
Eric Laurenta1d525f2015-01-29 13:36:45 -0800153 checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
François Gaffie2110e042015-03-24 08:41:51 +0100154
155 // Propagate device availability to Engine
156 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurente552edb2014-03-10 17:42:56 -0700157 } break;
158
159 default:
160 ALOGE("setDeviceConnectionState() invalid state: %x", state);
161 return BAD_VALUE;
162 }
163
Eric Laurent3a4311c2014-03-17 12:00:47 -0700164 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
165 // output is suspended before any tracks are moved to it
Eric Laurente552edb2014-03-10 17:42:56 -0700166 checkA2dpSuspend();
167 checkOutputForAllStrategies();
168 // outputs must be closed after checkOutputForAllStrategies() is executed
169 if (!outputs.isEmpty()) {
170 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700171 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -0700172 // close unused outputs after device disconnection or direct outputs that have been
173 // opened by checkOutputsForDevice() to query dynamic parameters
Eric Laurent3b73df72014-03-11 09:06:29 -0700174 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Eric Laurente552edb2014-03-10 17:42:56 -0700175 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
176 (desc->mDirectOpenCount == 0))) {
177 closeOutput(outputs[i]);
178 }
179 }
Eric Laurent3a4311c2014-03-17 12:00:47 -0700180 // check again after closing A2DP output to reset mA2dpSuspended if needed
181 checkA2dpSuspend();
Eric Laurente552edb2014-03-10 17:42:56 -0700182 }
183
184 updateDevicesAndOutputs();
Eric Laurent87ffa392015-05-22 10:32:38 -0700185 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700186 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
187 updateCallRouting(newDevice);
188 }
Eric Laurente552edb2014-03-10 17:42:56 -0700189 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700190 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
191 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
192 audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700193 // do not force device change on duplicated output because if device is 0, it will
194 // also force a device 0 for the two outputs it is duplicated to which may override
195 // a valid device selection on those outputs.
Eric Laurentc75307b2015-03-17 15:29:32 -0700196 bool force = !desc->isDuplicated()
François Gaffie53615e22015-03-19 09:24:12 +0100197 && (!device_distinguishes_on_address(device)
Eric Laurentc2730ba2014-07-20 15:47:07 -0700198 // always force when disconnecting (a non-duplicated device)
199 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
Eric Laurentc75307b2015-03-17 15:29:32 -0700200 setOutputDevice(desc, newDevice, force, 0);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700201 }
Eric Laurente552edb2014-03-10 17:42:56 -0700202 }
203
Eric Laurent72aa32f2014-05-30 18:51:48 -0700204 mpClientInterface->onAudioPortListUpdate();
Eric Laurentb71e58b2014-05-29 16:08:11 -0700205 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700206 } // end if is output device
207
Eric Laurente552edb2014-03-10 17:42:56 -0700208 // handle input devices
209 if (audio_is_input_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700210 SortedVector <audio_io_handle_t> inputs;
211
Eric Laurent3a4311c2014-03-17 12:00:47 -0700212 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700213 switch (state)
214 {
215 // handle input device connection
Eric Laurent3b73df72014-03-11 09:06:29 -0700216 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700217 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700218 ALOGW("setDeviceConnectionState() device already connected: %d", device);
219 return INVALID_OPERATION;
220 }
François Gaffie53615e22015-03-19 09:24:12 +0100221 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurent6a94d692014-05-20 11:18:06 -0700222 if (module == NULL) {
223 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
224 device);
225 return INVALID_OPERATION;
226 }
François Gaffie44481e72016-04-20 07:49:57 +0200227
228 // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
229 // parameters on newly connected devices (instead of opening the inputs...)
230 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
231
Paul McLean9080a4c2015-06-18 08:24:02 -0700232 if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
François Gaffie44481e72016-04-20 07:49:57 +0200233 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
234 devDesc->mAddress);
Eric Laurentd4692962014-05-05 18:13:44 -0700235 return INVALID_OPERATION;
236 }
237
Eric Laurent3a4311c2014-03-17 12:00:47 -0700238 index = mAvailableInputDevices.add(devDesc);
239 if (index >= 0) {
Paul McLeane743a472015-01-28 11:07:31 -0800240 mAvailableInputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700241 } else {
242 return NO_MEMORY;
243 }
Eric Laurent3ae5f312015-02-03 17:12:08 -0800244
François Gaffie2110e042015-03-24 08:41:51 +0100245 // Propagate device availability to Engine
246 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700247 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700248
249 // handle input device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700250 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700251 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700252 ALOGW("setDeviceConnectionState() device not connected: %d", device);
253 return INVALID_OPERATION;
254 }
Paul McLean5c477aa2014-08-20 16:47:57 -0700255
256 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
257
258 // Set Disconnect to HALs
François Gaffie44481e72016-04-20 07:49:57 +0200259 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700260
Paul McLean9080a4c2015-06-18 08:24:02 -0700261 checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700262 mAvailableInputDevices.remove(devDesc);
Paul McLean5c477aa2014-08-20 16:47:57 -0700263
François Gaffie2110e042015-03-24 08:41:51 +0100264 // Propagate device availability to Engine
265 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700266 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700267
268 default:
269 ALOGE("setDeviceConnectionState() invalid state: %x", state);
270 return BAD_VALUE;
271 }
272
Eric Laurentd4692962014-05-05 18:13:44 -0700273 closeAllInputs();
Eric Laurente552edb2014-03-10 17:42:56 -0700274
Eric Laurent87ffa392015-05-22 10:32:38 -0700275 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700276 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
277 updateCallRouting(newDevice);
278 }
279
Eric Laurentb52c1522014-05-20 11:27:36 -0700280 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700281 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700282 } // end if is input device
Eric Laurente552edb2014-03-10 17:42:56 -0700283
284 ALOGW("setDeviceConnectionState() invalid device: %x", device);
285 return BAD_VALUE;
286}
287
Eric Laurente0720872014-03-11 09:30:41 -0700288audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +0100289 const char *device_address)
Eric Laurente552edb2014-03-10 17:42:56 -0700290{
François Gaffie53615e22015-03-19 09:24:12 +0100291 sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(device, device_address, "");
292
Eric Laurent3a4311c2014-03-17 12:00:47 -0700293 DeviceVector *deviceVector;
294
Eric Laurente552edb2014-03-10 17:42:56 -0700295 if (audio_is_output_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700296 deviceVector = &mAvailableOutputDevices;
Eric Laurente552edb2014-03-10 17:42:56 -0700297 } else if (audio_is_input_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700298 deviceVector = &mAvailableInputDevices;
299 } else {
300 ALOGW("getDeviceConnectionState() invalid device type %08x", device);
301 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurente552edb2014-03-10 17:42:56 -0700302 }
François Gaffie53615e22015-03-19 09:24:12 +0100303 return deviceVector->getDeviceConnectionState(devDesc);
Eric Laurenta1d525f2015-01-29 13:36:45 -0800304}
305
Eric Laurentc2730ba2014-07-20 15:47:07 -0700306void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)
307{
308 bool createTxPatch = false;
309 struct audio_patch patch;
310 patch.num_sources = 1;
311 patch.num_sinks = 1;
312 status_t status;
313 audio_patch_handle_t afPatchHandle;
314 DeviceVector deviceList;
315
Eric Laurent87ffa392015-05-22 10:32:38 -0700316 if(!hasPrimaryOutput()) {
317 return;
318 }
Eric Laurentc73ca6e2014-12-12 14:34:22 -0800319 audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700320 ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
321
322 // release existing RX patch if any
323 if (mCallRxPatch != 0) {
324 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
325 mCallRxPatch.clear();
326 }
327 // release TX patch if any
328 if (mCallTxPatch != 0) {
329 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
330 mCallTxPatch.clear();
331 }
332
333 // If the RX device is on the primary HW module, then use legacy routing method for voice calls
334 // via setOutputDevice() on primary output.
335 // Otherwise, create two audio patches for TX and RX path.
336 if (availablePrimaryOutputDevices() & rxDevice) {
337 setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
338 // If the TX device is also on the primary HW module, setOutputDevice() will take care
339 // of it due to legacy implementation. If not, create a patch.
340 if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
341 == AUDIO_DEVICE_NONE) {
342 createTxPatch = true;
343 }
344 } else {
345 // create RX path audio patch
346 deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
347 ALOG_ASSERT(!deviceList.isEmpty(),
348 "updateCallRouting() selected device not in output device list");
349 sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
350 deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
351 ALOG_ASSERT(!deviceList.isEmpty(),
352 "updateCallRouting() no telephony RX device");
353 sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
354
355 rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
356 rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
357
358 // request to reuse existing output stream if one is already opened to reach the RX device
359 SortedVector<audio_io_handle_t> outputs =
360 getOutputsForDevice(rxDevice, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700361 audio_io_handle_t output = selectOutput(outputs,
362 AUDIO_OUTPUT_FLAG_NONE,
363 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700364 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700365 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700366 ALOG_ASSERT(!outputDesc->isDuplicated(),
367 "updateCallRouting() RX device output is duplicated");
368 outputDesc->toAudioPortConfig(&patch.sources[1]);
Eric Laurent3bcf8592015-04-03 12:13:24 -0700369 patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700370 patch.num_sources = 2;
371 }
372
373 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
374 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
375 ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
376 status);
377 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100378 mCallRxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700379 mCallRxPatch->mAfPatchHandle = afPatchHandle;
380 mCallRxPatch->mUid = mUidCached;
381 }
382 createTxPatch = true;
383 }
384 if (createTxPatch) {
385
386 struct audio_patch patch;
387 patch.num_sources = 1;
388 patch.num_sinks = 1;
389 deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
390 ALOG_ASSERT(!deviceList.isEmpty(),
391 "updateCallRouting() selected device not in input device list");
392 sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
393 txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
394 deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
395 ALOG_ASSERT(!deviceList.isEmpty(),
396 "updateCallRouting() no telephony TX device");
397 sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
398 txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
399
400 SortedVector<audio_io_handle_t> outputs =
401 getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700402 audio_io_handle_t output = selectOutput(outputs,
403 AUDIO_OUTPUT_FLAG_NONE,
404 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700405 // request to reuse existing output stream if one is already opened to reach the TX
406 // path output device
407 if (output != AUDIO_IO_HANDLE_NONE) {
408 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
409 ALOG_ASSERT(!outputDesc->isDuplicated(),
410 "updateCallRouting() RX device output is duplicated");
411 outputDesc->toAudioPortConfig(&patch.sources[1]);
Eric Laurent3bcf8592015-04-03 12:13:24 -0700412 patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700413 patch.num_sources = 2;
414 }
415
Eric Laurentc0a889f2015-10-14 14:36:34 -0700416 // terminate active capture if on the same HW module as the call TX source device
417 // FIXME: would be better to refine to only inputs whose profile connects to the
418 // call TX device but this information is not in the audio patch and logic here must be
419 // symmetric to the one in startInput()
420 audio_io_handle_t activeInput = mInputs.getActiveInput();
421 if (activeInput != 0) {
422 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
423 if (activeDesc->getModuleHandle() == txSourceDeviceDesc->getModuleHandle()) {
424 audio_session_t activeSession = activeDesc->mSessions.itemAt(0);
425 stopInput(activeInput, activeSession);
426 releaseInput(activeInput, activeSession);
427 }
428 }
429
Eric Laurentc2730ba2014-07-20 15:47:07 -0700430 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
431 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
432 ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
433 status);
434 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100435 mCallTxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700436 mCallTxPatch->mAfPatchHandle = afPatchHandle;
437 mCallTxPatch->mUid = mUidCached;
438 }
439 }
440}
441
Eric Laurente0720872014-03-11 09:30:41 -0700442void AudioPolicyManager::setPhoneState(audio_mode_t state)
Eric Laurente552edb2014-03-10 17:42:56 -0700443{
444 ALOGV("setPhoneState() state %d", state);
François Gaffie2110e042015-03-24 08:41:51 +0100445 // store previous phone state for management of sonification strategy below
446 int oldState = mEngine->getPhoneState();
447
448 if (mEngine->setPhoneState(state) != NO_ERROR) {
449 ALOGW("setPhoneState() invalid or same state %d", state);
Eric Laurente552edb2014-03-10 17:42:56 -0700450 return;
451 }
François Gaffie2110e042015-03-24 08:41:51 +0100452 /// Opens: can these line be executed after the switch of volume curves???
Eric Laurente552edb2014-03-10 17:42:56 -0700453 // if leaving call state, handle special case of active streams
454 // pertaining to sonification strategy see handleIncallSonification()
Eric Laurent63dea1d2015-07-02 17:10:28 -0700455 if (isStateInCall(oldState)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700456 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700457 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -0800458 if (stream == AUDIO_STREAM_PATCH) {
459 continue;
460 }
Eric Laurent3b73df72014-03-11 09:06:29 -0700461 handleIncallSonification((audio_stream_type_t)stream, false, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700462 }
Eric Laurent2cbe89a2014-12-19 11:49:08 -0800463
Eric Laurent63dea1d2015-07-02 17:10:28 -0700464 // force reevaluating accessibility routing when call stops
Eric Laurent2cbe89a2014-12-19 11:49:08 -0800465 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -0700466 }
467
François Gaffie2110e042015-03-24 08:41:51 +0100468 /**
469 * Switching to or from incall state or switching between telephony and VoIP lead to force
470 * routing command.
471 */
472 bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
473 || (is_state_in_call(state) && (state != oldState)));
Eric Laurente552edb2014-03-10 17:42:56 -0700474
475 // check for device and output changes triggered by new phone state
Eric Laurente552edb2014-03-10 17:42:56 -0700476 checkA2dpSuspend();
477 checkOutputForAllStrategies();
478 updateDevicesAndOutputs();
479
Eric Laurente552edb2014-03-10 17:42:56 -0700480 int delayMs = 0;
481 if (isStateInCall(state)) {
482 nsecs_t sysTime = systemTime();
483 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700484 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700485 // mute media and sonification strategies and delay device switch by the largest
486 // latency of any output where either strategy is active.
487 // This avoid sending the ring tone or music tail into the earpiece or headset.
François Gaffiead3183e2015-03-18 16:55:35 +0100488 if ((isStrategyActive(desc, STRATEGY_MEDIA,
489 SONIFICATION_HEADSET_MUSIC_DELAY,
490 sysTime) ||
491 isStrategyActive(desc, STRATEGY_SONIFICATION,
492 SONIFICATION_HEADSET_MUSIC_DELAY,
493 sysTime)) &&
Eric Laurentc75307b2015-03-17 15:29:32 -0700494 (delayMs < (int)desc->latency()*2)) {
495 delayMs = desc->latency()*2;
Eric Laurente552edb2014-03-10 17:42:56 -0700496 }
Eric Laurentc75307b2015-03-17 15:29:32 -0700497 setStrategyMute(STRATEGY_MEDIA, true, desc);
498 setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
Eric Laurente552edb2014-03-10 17:42:56 -0700499 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
Eric Laurentc75307b2015-03-17 15:29:32 -0700500 setStrategyMute(STRATEGY_SONIFICATION, true, desc);
501 setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
Eric Laurente552edb2014-03-10 17:42:56 -0700502 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
503 }
504 }
505
Eric Laurent87ffa392015-05-22 10:32:38 -0700506 if (hasPrimaryOutput()) {
507 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
508 // the device returned is not necessarily reachable via this output
509 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
510 // force routing command to audio hardware when ending call
511 // even if no device change is needed
512 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
513 rxDevice = mPrimaryOutput->device();
514 }
Eric Laurente552edb2014-03-10 17:42:56 -0700515
Eric Laurent87ffa392015-05-22 10:32:38 -0700516 if (state == AUDIO_MODE_IN_CALL) {
517 updateCallRouting(rxDevice, delayMs);
518 } else if (oldState == AUDIO_MODE_IN_CALL) {
519 if (mCallRxPatch != 0) {
520 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
521 mCallRxPatch.clear();
522 }
523 if (mCallTxPatch != 0) {
524 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
525 mCallTxPatch.clear();
526 }
527 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
528 } else {
529 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700530 }
Eric Laurentc2730ba2014-07-20 15:47:07 -0700531 }
Eric Laurente552edb2014-03-10 17:42:56 -0700532 // if entering in call state, handle special case of active streams
533 // pertaining to sonification strategy see handleIncallSonification()
534 if (isStateInCall(state)) {
535 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700536 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -0800537 if (stream == AUDIO_STREAM_PATCH) {
538 continue;
539 }
Eric Laurent3b73df72014-03-11 09:06:29 -0700540 handleIncallSonification((audio_stream_type_t)stream, true, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700541 }
Eric Laurent63dea1d2015-07-02 17:10:28 -0700542
543 // force reevaluating accessibility routing when call starts
544 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -0700545 }
546
547 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
Eric Laurent3b73df72014-03-11 09:06:29 -0700548 if (state == AUDIO_MODE_RINGTONE &&
549 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700550 mLimitRingtoneVolume = true;
551 } else {
552 mLimitRingtoneVolume = false;
553 }
554}
555
Jean-Michel Trivi887a9ed2015-03-31 18:02:24 -0700556audio_mode_t AudioPolicyManager::getPhoneState() {
557 return mEngine->getPhoneState();
558}
559
Eric Laurente0720872014-03-11 09:30:41 -0700560void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
Eric Laurent3b73df72014-03-11 09:06:29 -0700561 audio_policy_forced_cfg_t config)
Eric Laurente552edb2014-03-10 17:42:56 -0700562{
François Gaffie2110e042015-03-24 08:41:51 +0100563 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
Eric Laurente552edb2014-03-10 17:42:56 -0700564
François Gaffie2110e042015-03-24 08:41:51 +0100565 if (mEngine->setForceUse(usage, config) != NO_ERROR) {
566 ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
567 return;
Eric Laurente552edb2014-03-10 17:42:56 -0700568 }
François Gaffie2110e042015-03-24 08:41:51 +0100569 bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
570 (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
571 (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
Eric Laurente552edb2014-03-10 17:42:56 -0700572
573 // check for device and output changes triggered by new force usage
574 checkA2dpSuspend();
575 checkOutputForAllStrategies();
576 updateDevicesAndOutputs();
Eric Laurent87ffa392015-05-22 10:32:38 -0700577 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700578 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
579 updateCallRouting(newDevice);
580 }
Eric Laurente552edb2014-03-10 17:42:56 -0700581 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700582 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
583 audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
584 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
585 setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE));
Eric Laurentc2730ba2014-07-20 15:47:07 -0700586 }
Eric Laurente552edb2014-03-10 17:42:56 -0700587 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700588 applyStreamVolumes(outputDesc, newDevice, 0, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700589 }
590 }
591
François Gaffie53615e22015-03-19 09:24:12 +0100592 audio_io_handle_t activeInput = mInputs.getActiveInput();
Eric Laurente552edb2014-03-10 17:42:56 -0700593 if (activeInput != 0) {
Eric Laurentc171c7c2015-09-25 12:21:06 -0700594 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
595 audio_devices_t newDevice = getNewInputDevice(activeInput);
596 // Force new input selection if the new device can not be reached via current input
597 if (activeDesc->mProfile->mSupportedDevices.types() & (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
598 setInputDevice(activeInput, newDevice);
599 } else {
600 closeInput(activeInput);
601 }
Eric Laurente552edb2014-03-10 17:42:56 -0700602 }
Eric Laurente552edb2014-03-10 17:42:56 -0700603}
604
Eric Laurente0720872014-03-11 09:30:41 -0700605void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
Eric Laurente552edb2014-03-10 17:42:56 -0700606{
607 ALOGV("setSystemProperty() property %s, value %s", property, value);
608}
609
610// Find a direct output profile compatible with the parameters passed, even if the input flags do
611// not explicitly request a direct output
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -0800612sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
Eric Laurente552edb2014-03-10 17:42:56 -0700613 audio_devices_t device,
614 uint32_t samplingRate,
615 audio_format_t format,
616 audio_channel_mask_t channelMask,
617 audio_output_flags_t flags)
618{
Eric Laurent861a6282015-05-18 15:40:16 -0700619 // only retain flags that will drive the direct output profile selection
620 // if explicitly requested
621 static const uint32_t kRelevantFlags =
622 (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
623 flags =
624 (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
625
626 sp<IOProfile> profile;
627
Eric Laurente552edb2014-03-10 17:42:56 -0700628 for (size_t i = 0; i < mHwModules.size(); i++) {
629 if (mHwModules[i]->mHandle == 0) {
630 continue;
631 }
632 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
Eric Laurent861a6282015-05-18 15:40:16 -0700633 sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
634 if (!curProfile->isCompatibleProfile(device, String8(""),
Andy Hungf129b032015-04-07 13:45:50 -0700635 samplingRate, NULL /*updatedSamplingRate*/,
636 format, NULL /*updatedFormat*/,
637 channelMask, NULL /*updatedChannelMask*/,
Eric Laurent861a6282015-05-18 15:40:16 -0700638 flags)) {
639 continue;
640 }
641 // reject profiles not corresponding to a device currently available
642 if ((mAvailableOutputDevices.types() & curProfile->mSupportedDevices.types()) == 0) {
643 continue;
644 }
645 // if several profiles are compatible, give priority to one with offload capability
646 if (profile != 0 && ((curProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
647 continue;
648 }
649 profile = curProfile;
650 if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
651 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700652 }
Eric Laurente552edb2014-03-10 17:42:56 -0700653 }
654 }
Eric Laurent861a6282015-05-18 15:40:16 -0700655 return profile;
Eric Laurente552edb2014-03-10 17:42:56 -0700656}
657
Eric Laurente0720872014-03-11 09:30:41 -0700658audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +0100659 uint32_t samplingRate,
660 audio_format_t format,
661 audio_channel_mask_t channelMask,
662 audio_output_flags_t flags,
663 const audio_offload_info_t *offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -0700664{
Eric Laurent3b73df72014-03-11 09:06:29 -0700665 routing_strategy strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -0700666 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
667 ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
668 device, stream, samplingRate, format, channelMask, flags);
669
Eric Laurente83b55d2014-11-14 10:06:21 -0800670 return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE,
671 stream, samplingRate,format, channelMask,
672 flags, offloadInfo);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700673}
674
Eric Laurente83b55d2014-11-14 10:06:21 -0800675status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
676 audio_io_handle_t *output,
677 audio_session_t session,
678 audio_stream_type_t *stream,
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700679 uid_t uid,
Eric Laurente83b55d2014-11-14 10:06:21 -0800680 uint32_t samplingRate,
681 audio_format_t format,
682 audio_channel_mask_t channelMask,
683 audio_output_flags_t flags,
Paul McLeanaa981192015-03-21 09:55:15 -0700684 audio_port_handle_t selectedDeviceId,
Eric Laurente83b55d2014-11-14 10:06:21 -0800685 const audio_offload_info_t *offloadInfo)
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700686{
Eric Laurente83b55d2014-11-14 10:06:21 -0800687 audio_attributes_t attributes;
688 if (attr != NULL) {
689 if (!isValidAttributes(attr)) {
690 ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
691 attr->usage, attr->content_type, attr->flags,
692 attr->tags);
693 return BAD_VALUE;
694 }
695 attributes = *attr;
696 } else {
697 if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
698 ALOGE("getOutputForAttr(): invalid stream type");
699 return BAD_VALUE;
700 }
701 stream_type_to_audio_attributes(*stream, &attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700702 }
Eric Laurentc75307b2015-03-17 15:29:32 -0700703 sp<SwAudioOutputDescriptor> desc;
François Gaffie036e1e92015-03-19 10:16:24 +0100704 if (mPolicyMixes.getOutputForAttr(attributes, desc) == NO_ERROR) {
705 ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
706 if (!audio_is_linear_pcm(format)) {
707 return BAD_VALUE;
Eric Laurent275e8e92014-11-30 15:14:47 -0800708 }
François Gaffie036e1e92015-03-19 10:16:24 +0100709 *stream = streamTypefromAttributesInt(&attributes);
710 *output = desc->mIoHandle;
711 ALOGV("getOutputForAttr() returns output %d", *output);
712 return NO_ERROR;
Eric Laurent275e8e92014-11-30 15:14:47 -0800713 }
714 if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
715 ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
716 return BAD_VALUE;
717 }
718
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700719 ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
720 " session %d selectedDeviceId %d",
721 attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
722 session, selectedDeviceId);
723
724 *stream = streamTypefromAttributesInt(&attributes);
725
726 // Explicit routing?
727 sp<DeviceDescriptor> deviceDesc;
728 for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
729 if (mAvailableOutputDevices[i]->getId() == selectedDeviceId) {
730 deviceDesc = mAvailableOutputDevices[i];
731 break;
732 }
733 }
734 mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700735
Eric Laurente83b55d2014-11-14 10:06:21 -0800736 routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700737 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
Eric Laurent93c3d412014-08-01 14:48:35 -0700738
Eric Laurente83b55d2014-11-14 10:06:21 -0800739 if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
Eric Laurent93c3d412014-08-01 14:48:35 -0700740 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
741 }
742
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -0700743 ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700744 device, samplingRate, format, channelMask, flags);
745
Eric Laurente83b55d2014-11-14 10:06:21 -0800746 *output = getOutputForDevice(device, session, *stream,
747 samplingRate, format, channelMask,
748 flags, offloadInfo);
749 if (*output == AUDIO_IO_HANDLE_NONE) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700750 mOutputRoutes.removeRoute(session);
Eric Laurente83b55d2014-11-14 10:06:21 -0800751 return INVALID_OPERATION;
752 }
Paul McLeanaa981192015-03-21 09:55:15 -0700753
Eric Laurente83b55d2014-11-14 10:06:21 -0800754 return NO_ERROR;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700755}
756
757audio_io_handle_t AudioPolicyManager::getOutputForDevice(
758 audio_devices_t device,
Eric Laurentcaf7f482014-11-25 17:50:47 -0800759 audio_session_t session __unused,
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700760 audio_stream_type_t stream,
761 uint32_t samplingRate,
762 audio_format_t format,
763 audio_channel_mask_t channelMask,
764 audio_output_flags_t flags,
765 const audio_offload_info_t *offloadInfo)
766{
Eric Laurentcf2c0212014-07-25 16:20:43 -0700767 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700768 uint32_t latency = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700769 status_t status;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700770
Eric Laurente552edb2014-03-10 17:42:56 -0700771#ifdef AUDIO_POLICY_TEST
772 if (mCurOutput != 0) {
773 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
774 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
775
776 if (mTestOutputs[mCurOutput] == 0) {
777 ALOGV("getOutput() opening test output");
Eric Laurentc75307b2015-03-17 15:29:32 -0700778 sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
779 mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -0700780 outputDesc->mDevice = mTestDevice;
Eric Laurente552edb2014-03-10 17:42:56 -0700781 outputDesc->mLatency = mTestLatencyMs;
Eric Laurent3b73df72014-03-11 09:06:29 -0700782 outputDesc->mFlags =
783 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
Eric Laurente552edb2014-03-10 17:42:56 -0700784 outputDesc->mRefCount[stream] = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700785 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
786 config.sample_rate = mTestSamplingRate;
787 config.channel_mask = mTestChannels;
788 config.format = mTestFormat;
Phil Burk77cce802014-08-04 16:18:15 -0700789 if (offloadInfo != NULL) {
790 config.offload_info = *offloadInfo;
791 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700792 status = mpClientInterface->openOutput(0,
793 &mTestOutputs[mCurOutput],
794 &config,
795 &outputDesc->mDevice,
796 String8(""),
797 &outputDesc->mLatency,
798 outputDesc->mFlags);
799 if (status == NO_ERROR) {
800 outputDesc->mSamplingRate = config.sample_rate;
801 outputDesc->mFormat = config.format;
802 outputDesc->mChannelMask = config.channel_mask;
Eric Laurente552edb2014-03-10 17:42:56 -0700803 AudioParameter outputCmd = AudioParameter();
804 outputCmd.addInt(String8("set_id"),mCurOutput);
805 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
806 addOutput(mTestOutputs[mCurOutput], outputDesc);
807 }
808 }
809 return mTestOutputs[mCurOutput];
810 }
811#endif //AUDIO_POLICY_TEST
812
813 // open a direct output if required by specified parameters
814 //force direct flag if offload flag is set: offloading implies a direct output stream
815 // and all common behaviors are driven by checking only the direct flag
816 // this should normally be set appropriately in the policy configuration file
817 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700818 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurente552edb2014-03-10 17:42:56 -0700819 }
Eric Laurent93c3d412014-08-01 14:48:35 -0700820 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
821 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
822 }
Eric Laurente83b55d2014-11-14 10:06:21 -0800823 // only allow deep buffering for music stream type
824 if (stream != AUDIO_STREAM_MUSIC) {
825 flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
Ravi Kumar Alamanda439e4ed2015-04-03 12:13:21 -0700826 } else if (/* stream == AUDIO_STREAM_MUSIC && */
827 flags == AUDIO_OUTPUT_FLAG_NONE &&
828 property_get_bool("audio.deep_buffer.media", false /* default_value */)) {
829 // use DEEP_BUFFER as default output for music stream type
830 flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
Eric Laurente83b55d2014-11-14 10:06:21 -0800831 }
Ravi Kumar Alamandac36a8892015-04-24 16:35:49 -0700832 if (stream == AUDIO_STREAM_TTS) {
833 flags = AUDIO_OUTPUT_FLAG_TTS;
834 }
Eric Laurente552edb2014-03-10 17:42:56 -0700835
Eric Laurentb732cf52014-09-24 19:08:21 -0700836 sp<IOProfile> profile;
837
838 // skip direct output selection if the request can obviously be attached to a mixed output
Eric Laurentc2607842014-09-29 09:43:03 -0700839 // and not explicitly requested
840 if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
841 audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
Eric Laurentb732cf52014-09-24 19:08:21 -0700842 audio_channel_count_from_out_mask(channelMask) <= 2) {
843 goto non_direct_output;
844 }
845
Eric Laurente552edb2014-03-10 17:42:56 -0700846 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
847 // creating an offloaded track and tearing it down immediately after start when audioflinger
848 // detects there is an active non offloadable effect.
849 // FIXME: We should check the audio session here but we do not have it in this context.
850 // This may prevent offloading in rare situations where effects are left active by apps
851 // in the background.
Eric Laurentb732cf52014-09-24 19:08:21 -0700852
Eric Laurente552edb2014-03-10 17:42:56 -0700853 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
François Gaffie45ed3b02015-03-19 10:35:14 +0100854 !mEffects.isNonOffloadableEffectEnabled()) {
Eric Laurente552edb2014-03-10 17:42:56 -0700855 profile = getProfileForDirectOutput(device,
856 samplingRate,
857 format,
858 channelMask,
859 (audio_output_flags_t)flags);
860 }
861
Eric Laurent1c333e22014-05-20 10:48:17 -0700862 if (profile != 0) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700863 sp<SwAudioOutputDescriptor> outputDesc = NULL;
Eric Laurente552edb2014-03-10 17:42:56 -0700864
865 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700866 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700867 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
868 outputDesc = desc;
869 // reuse direct output if currently open and configured with same parameters
870 if ((samplingRate == outputDesc->mSamplingRate) &&
871 (format == outputDesc->mFormat) &&
872 (channelMask == outputDesc->mChannelMask)) {
873 outputDesc->mDirectOpenCount++;
874 ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
875 return mOutputs.keyAt(i);
876 }
877 }
878 }
879 // close direct output if currently open and configured with different parameters
880 if (outputDesc != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700881 closeOutput(outputDesc->mIoHandle);
Eric Laurente552edb2014-03-10 17:42:56 -0700882 }
Eric Laurent861a6282015-05-18 15:40:16 -0700883
884 // if the selected profile is offloaded and no offload info was specified,
885 // create a default one
886 audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
887 if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
888 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
889 defaultOffloadInfo.sample_rate = samplingRate;
890 defaultOffloadInfo.channel_mask = channelMask;
891 defaultOffloadInfo.format = format;
892 defaultOffloadInfo.stream_type = stream;
893 defaultOffloadInfo.bit_rate = 0;
894 defaultOffloadInfo.duration_us = -1;
895 defaultOffloadInfo.has_video = true; // conservative
896 defaultOffloadInfo.is_streaming = true; // likely
897 offloadInfo = &defaultOffloadInfo;
898 }
899
Eric Laurentc75307b2015-03-17 15:29:32 -0700900 outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -0700901 outputDesc->mDevice = device;
Eric Laurente552edb2014-03-10 17:42:56 -0700902 outputDesc->mLatency = 0;
Eric Laurent861a6282015-05-18 15:40:16 -0700903 outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700904 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
905 config.sample_rate = samplingRate;
906 config.channel_mask = channelMask;
907 config.format = format;
Phil Burk77cce802014-08-04 16:18:15 -0700908 if (offloadInfo != NULL) {
909 config.offload_info = *offloadInfo;
910 }
Eric Laurent322b4d22015-04-03 15:57:54 -0700911 status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -0700912 &output,
913 &config,
914 &outputDesc->mDevice,
915 String8(""),
916 &outputDesc->mLatency,
917 outputDesc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -0700918
919 // only accept an output with the requested parameters
Eric Laurentcf2c0212014-07-25 16:20:43 -0700920 if (status != NO_ERROR ||
921 (samplingRate != 0 && samplingRate != config.sample_rate) ||
922 (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
923 (channelMask != 0 && channelMask != config.channel_mask)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700924 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
925 "format %d %d, channelMask %04x %04x", output, samplingRate,
926 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
927 outputDesc->mChannelMask);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700928 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -0700929 mpClientInterface->closeOutput(output);
930 }
Eric Laurenta82797f2015-01-30 11:49:43 -0800931 // fall back to mixer output if possible when the direct output could not be open
932 if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
933 goto non_direct_output;
934 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700935 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -0700936 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700937 outputDesc->mSamplingRate = config.sample_rate;
938 outputDesc->mChannelMask = config.channel_mask;
939 outputDesc->mFormat = config.format;
940 outputDesc->mRefCount[stream] = 0;
941 outputDesc->mStopTime[stream] = 0;
942 outputDesc->mDirectOpenCount = 1;
943
Eric Laurente552edb2014-03-10 17:42:56 -0700944 audio_io_handle_t srcOutput = getOutputForEffect();
945 addOutput(output, outputDesc);
946 audio_io_handle_t dstOutput = getOutputForEffect();
947 if (dstOutput == output) {
948 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
949 }
950 mPreviousOutputs = mOutputs;
951 ALOGV("getOutput() returns new direct output %d", output);
Eric Laurentb52c1522014-05-20 11:27:36 -0700952 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700953 return output;
954 }
955
Eric Laurentb732cf52014-09-24 19:08:21 -0700956non_direct_output:
Eric Laurente552edb2014-03-10 17:42:56 -0700957 // ignoring channel mask due to downmix capability in mixer
958
959 // open a non direct output
960
961 // for non direct outputs, only PCM is supported
962 if (audio_is_linear_pcm(format)) {
963 // get which output is suitable for the specified stream. The actual
964 // routing change will happen when startOutput() will be called
965 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
966
Eric Laurent8838a382014-09-08 16:44:28 -0700967 // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
968 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
969 output = selectOutput(outputs, flags, format);
Eric Laurente552edb2014-03-10 17:42:56 -0700970 }
971 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
972 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
973
Paul McLeanaa981192015-03-21 09:55:15 -0700974 ALOGV(" getOutputForDevice() returns output %d", output);
Eric Laurente552edb2014-03-10 17:42:56 -0700975
976 return output;
977}
978
Eric Laurente0720872014-03-11 09:30:41 -0700979audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
Eric Laurent8838a382014-09-08 16:44:28 -0700980 audio_output_flags_t flags,
981 audio_format_t format)
Eric Laurente552edb2014-03-10 17:42:56 -0700982{
983 // select one output among several that provide a path to a particular device or set of
984 // devices (the list was previously build by getOutputsForDevice()).
985 // The priority is as follows:
986 // 1: the output with the highest number of requested policy flags
987 // 2: the primary output
988 // 3: the first output in the list
989
990 if (outputs.size() == 0) {
991 return 0;
992 }
993 if (outputs.size() == 1) {
994 return outputs[0];
995 }
996
997 int maxCommonFlags = 0;
998 audio_io_handle_t outputFlags = 0;
999 audio_io_handle_t outputPrimary = 0;
1000
1001 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001002 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -07001003 if (!outputDesc->isDuplicated()) {
Eric Laurent8838a382014-09-08 16:44:28 -07001004 // if a valid format is specified, skip output if not compatible
1005 if (format != AUDIO_FORMAT_INVALID) {
1006 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
1007 if (format != outputDesc->mFormat) {
1008 continue;
1009 }
1010 } else if (!audio_is_linear_pcm(format)) {
1011 continue;
1012 }
1013 }
1014
Eric Laurent3b73df72014-03-11 09:06:29 -07001015 int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001016 if (commonFlags > maxCommonFlags) {
1017 outputFlags = outputs[i];
1018 maxCommonFlags = commonFlags;
1019 ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
1020 }
1021 if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1022 outputPrimary = outputs[i];
1023 }
1024 }
1025 }
1026
1027 if (outputFlags != 0) {
1028 return outputFlags;
1029 }
1030 if (outputPrimary != 0) {
1031 return outputPrimary;
1032 }
1033
1034 return outputs[0];
1035}
1036
Eric Laurente0720872014-03-11 09:30:41 -07001037status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001038 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -08001039 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001040{
Paul McLeanaa981192015-03-21 09:55:15 -07001041 ALOGV("startOutput() output %d, stream %d, session %d",
1042 output, stream, session);
Eric Laurente552edb2014-03-10 17:42:56 -07001043 ssize_t index = mOutputs.indexOfKey(output);
1044 if (index < 0) {
1045 ALOGW("startOutput() unknown output %d", output);
1046 return BAD_VALUE;
1047 }
1048
Eric Laurentc75307b2015-03-17 15:29:32 -07001049 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1050
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001051 // Routing?
1052 mOutputRoutes.incRouteActivity(session);
1053
Eric Laurentc75307b2015-03-17 15:29:32 -07001054 audio_devices_t newDevice;
1055 if (outputDesc->mPolicyMix != NULL) {
1056 newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Eric Laurent493404d2015-04-21 15:07:36 -07001057 } else if (mOutputRoutes.hasRouteChanged(session)) {
1058 newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001059 checkStrategyRoute(getStrategy(stream), output);
Eric Laurentc75307b2015-03-17 15:29:32 -07001060 } else {
1061 newDevice = AUDIO_DEVICE_NONE;
1062 }
1063
1064 uint32_t delayMs = 0;
1065
Eric Laurentc75307b2015-03-17 15:29:32 -07001066 status_t status = startSource(outputDesc, stream, newDevice, &delayMs);
1067
1068 if (status != NO_ERROR) {
1069 mOutputRoutes.decRouteActivity(session);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001070 return status;
Eric Laurentc75307b2015-03-17 15:29:32 -07001071 }
1072 // Automatically enable the remote submix input when output is started on a re routing mix
1073 // of type MIX_TYPE_RECORDERS
1074 if (audio_is_remote_submix_device(newDevice) && outputDesc->mPolicyMix != NULL &&
1075 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1076 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1077 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1078 outputDesc->mPolicyMix->mRegistrationId,
1079 "remote-submix");
1080 }
1081
1082 if (delayMs != 0) {
1083 usleep(delayMs * 1000);
1084 }
1085
1086 return status;
1087}
1088
1089status_t AudioPolicyManager::startSource(sp<AudioOutputDescriptor> outputDesc,
1090 audio_stream_type_t stream,
1091 audio_devices_t device,
1092 uint32_t *delayMs)
1093{
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001094 // cannot start playback of STREAM_TTS if any other output is being used
1095 uint32_t beaconMuteLatency = 0;
Eric Laurentc75307b2015-03-17 15:29:32 -07001096
1097 *delayMs = 0;
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001098 if (stream == AUDIO_STREAM_TTS) {
1099 ALOGV("\t found BEACON stream");
Eric Laurent9459fb02015-08-12 18:36:32 -07001100 if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001101 return INVALID_OPERATION;
1102 } else {
1103 beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1104 }
1105 } else {
1106 // some playback other than beacon starts
1107 beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1108 }
1109
Eric Laurent7c1ec5f2015-07-09 14:52:47 -07001110 // check active before incrementing usage count
1111 bool force = !outputDesc->isActive();
1112
Eric Laurente552edb2014-03-10 17:42:56 -07001113 // increment usage count for this stream on the requested output:
1114 // NOTE that the usage count is the same for duplicated output and hardware output which is
1115 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1116 outputDesc->changeRefCount(stream, 1);
1117
Eric Laurent493404d2015-04-21 15:07:36 -07001118 if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001119 // starting an output being rerouted?
Eric Laurentc75307b2015-03-17 15:29:32 -07001120 if (device == AUDIO_DEVICE_NONE) {
1121 device = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurent275e8e92014-11-30 15:14:47 -08001122 }
Eric Laurente552edb2014-03-10 17:42:56 -07001123 routing_strategy strategy = getStrategy(stream);
1124 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001125 (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1126 (beaconMuteLatency > 0);
1127 uint32_t waitMs = beaconMuteLatency;
Eric Laurente552edb2014-03-10 17:42:56 -07001128 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001129 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001130 if (desc != outputDesc) {
1131 // force a device change if any other output is managed by the same hw
1132 // module and has a current device selection that differs from selected device.
1133 // In this case, the audio HAL must receive the new device selection so that it can
1134 // change the device currently selected by the other active output.
1135 if (outputDesc->sharesHwModuleWith(desc) &&
Eric Laurentc75307b2015-03-17 15:29:32 -07001136 desc->device() != device) {
Eric Laurente552edb2014-03-10 17:42:56 -07001137 force = true;
1138 }
1139 // wait for audio on other active outputs to be presented when starting
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001140 // a notification so that audio focus effect can propagate, or that a mute/unmute
1141 // event occurred for beacon
Eric Laurente552edb2014-03-10 17:42:56 -07001142 uint32_t latency = desc->latency();
1143 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1144 waitMs = latency;
1145 }
1146 }
1147 }
Eric Laurentc75307b2015-03-17 15:29:32 -07001148 uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force);
Eric Laurente552edb2014-03-10 17:42:56 -07001149
1150 // handle special case for sonification while in call
1151 if (isInCall()) {
1152 handleIncallSonification(stream, true, false);
1153 }
1154
1155 // apply volume rules for current stream and device if necessary
1156 checkAndSetVolume(stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07001157 mStreams.valueFor(stream).getVolumeIndex(device),
1158 outputDesc,
1159 device);
Eric Laurente552edb2014-03-10 17:42:56 -07001160
1161 // update the outputs if starting an output with a stream that can affect notification
1162 // routing
1163 handleNotificationRoutingForStream(stream);
Eric Laurentc722f302014-12-10 11:21:49 -08001164
Eric Laurent2cbe89a2014-12-19 11:49:08 -08001165 // force reevaluating accessibility routing when ringtone or alarm starts
1166 if (strategy == STRATEGY_SONIFICATION) {
1167 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
1168 }
Eric Laurente552edb2014-03-10 17:42:56 -07001169 }
1170 return NO_ERROR;
1171}
1172
1173
Eric Laurente0720872014-03-11 09:30:41 -07001174status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001175 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -08001176 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001177{
1178 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1179 ssize_t index = mOutputs.indexOfKey(output);
1180 if (index < 0) {
1181 ALOGW("stopOutput() unknown output %d", output);
1182 return BAD_VALUE;
1183 }
1184
Eric Laurentc75307b2015-03-17 15:29:32 -07001185 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001186
Eric Laurentc75307b2015-03-17 15:29:32 -07001187 if (outputDesc->mRefCount[stream] == 1) {
1188 // Automatically disable the remote submix input when output is stopped on a
1189 // re routing mix of type MIX_TYPE_RECORDERS
1190 if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1191 outputDesc->mPolicyMix != NULL &&
1192 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1193 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1194 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
1195 outputDesc->mPolicyMix->mRegistrationId,
1196 "remote-submix");
1197 }
1198 }
1199
1200 // Routing?
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001201 bool forceDeviceUpdate = false;
Eric Laurentc75307b2015-03-17 15:29:32 -07001202 if (outputDesc->mRefCount[stream] > 0) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001203 int activityCount = mOutputRoutes.decRouteActivity(session);
1204 forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
1205
1206 if (forceDeviceUpdate) {
1207 checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
1208 }
Eric Laurentc75307b2015-03-17 15:29:32 -07001209 }
1210
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001211 return stopSource(outputDesc, stream, forceDeviceUpdate);
Eric Laurentc75307b2015-03-17 15:29:32 -07001212}
1213
1214status_t AudioPolicyManager::stopSource(sp<AudioOutputDescriptor> outputDesc,
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001215 audio_stream_type_t stream,
1216 bool forceDeviceUpdate)
Eric Laurentc75307b2015-03-17 15:29:32 -07001217{
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001218 // always handle stream stop, check which stream type is stopping
1219 handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1220
Eric Laurente552edb2014-03-10 17:42:56 -07001221 // handle special case for sonification while in call
1222 if (isInCall()) {
1223 handleIncallSonification(stream, false, false);
1224 }
1225
1226 if (outputDesc->mRefCount[stream] > 0) {
1227 // decrement usage count of this stream on the output
1228 outputDesc->changeRefCount(stream, -1);
Paul McLeanaa981192015-03-21 09:55:15 -07001229
Eric Laurente552edb2014-03-10 17:42:56 -07001230 // store time at which the stream was stopped - see isStreamActive()
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001231 if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
Eric Laurente552edb2014-03-10 17:42:56 -07001232 outputDesc->mStopTime[stream] = systemTime();
Eric Laurentc75307b2015-03-17 15:29:32 -07001233 audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurente552edb2014-03-10 17:42:56 -07001234 // delay the device switch by twice the latency because stopOutput() is executed when
1235 // the track stop() command is received and at that time the audio track buffer can
1236 // still contain data that needs to be drained. The latency only covers the audio HAL
1237 // and kernel buffers. Also the latency does not always include additional delay in the
1238 // audio path (audio DSP, CODEC ...)
Eric Laurentc75307b2015-03-17 15:29:32 -07001239 setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
Eric Laurente552edb2014-03-10 17:42:56 -07001240
1241 // force restoring the device selection on other active outputs if it differs from the
1242 // one being selected for this output
1243 for (size_t i = 0; i < mOutputs.size(); i++) {
1244 audio_io_handle_t curOutput = mOutputs.keyAt(i);
Eric Laurent1f2f2232014-06-02 12:01:23 -07001245 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurentc75307b2015-03-17 15:29:32 -07001246 if (desc != outputDesc &&
Eric Laurente552edb2014-03-10 17:42:56 -07001247 desc->isActive() &&
1248 outputDesc->sharesHwModuleWith(desc) &&
1249 (newDevice != desc->device())) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001250 setOutputDevice(desc,
1251 getNewOutputDevice(desc, false /*fromCache*/),
Eric Laurente552edb2014-03-10 17:42:56 -07001252 true,
Eric Laurentc75307b2015-03-17 15:29:32 -07001253 outputDesc->latency()*2);
Eric Laurente552edb2014-03-10 17:42:56 -07001254 }
1255 }
1256 // update the outputs if stopping one with a stream that can affect notification routing
1257 handleNotificationRoutingForStream(stream);
1258 }
1259 return NO_ERROR;
1260 } else {
Eric Laurentc75307b2015-03-17 15:29:32 -07001261 ALOGW("stopOutput() refcount is already 0");
Eric Laurente552edb2014-03-10 17:42:56 -07001262 return INVALID_OPERATION;
1263 }
1264}
1265
Eric Laurente83b55d2014-11-14 10:06:21 -08001266void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
Eric Laurentcaf7f482014-11-25 17:50:47 -08001267 audio_stream_type_t stream __unused,
1268 audio_session_t session __unused)
Eric Laurente552edb2014-03-10 17:42:56 -07001269{
1270 ALOGV("releaseOutput() %d", output);
1271 ssize_t index = mOutputs.indexOfKey(output);
1272 if (index < 0) {
1273 ALOGW("releaseOutput() releasing unknown output %d", output);
1274 return;
1275 }
1276
1277#ifdef AUDIO_POLICY_TEST
1278 int testIndex = testOutputIndex(output);
1279 if (testIndex != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001280 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001281 if (outputDesc->isActive()) {
1282 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01001283 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07001284 mTestOutputs[testIndex] = 0;
1285 }
1286 return;
1287 }
1288#endif //AUDIO_POLICY_TEST
1289
Paul McLeanaa981192015-03-21 09:55:15 -07001290 // Routing
1291 mOutputRoutes.removeRoute(session);
1292
Eric Laurentc75307b2015-03-17 15:29:32 -07001293 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
Eric Laurent3b73df72014-03-11 09:06:29 -07001294 if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
Eric Laurente552edb2014-03-10 17:42:56 -07001295 if (desc->mDirectOpenCount <= 0) {
1296 ALOGW("releaseOutput() invalid open count %d for output %d",
1297 desc->mDirectOpenCount, output);
1298 return;
1299 }
1300 if (--desc->mDirectOpenCount == 0) {
1301 closeOutput(output);
1302 // If effects where present on the output, audioflinger moved them to the primary
1303 // output by default: move them back to the appropriate output.
1304 audio_io_handle_t dstOutput = getOutputForEffect();
Eric Laurent87ffa392015-05-22 10:32:38 -07001305 if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001306 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
1307 mPrimaryOutput->mIoHandle, dstOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07001308 }
Eric Laurentb52c1522014-05-20 11:27:36 -07001309 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001310 }
1311 }
1312}
1313
1314
Eric Laurentcaf7f482014-11-25 17:50:47 -08001315status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1316 audio_io_handle_t *input,
1317 audio_session_t session,
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001318 uid_t uid,
Eric Laurentcaf7f482014-11-25 17:50:47 -08001319 uint32_t samplingRate,
1320 audio_format_t format,
1321 audio_channel_mask_t channelMask,
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001322 audio_input_flags_t flags,
Paul McLean466dc8e2015-04-17 13:15:36 -06001323 audio_port_handle_t selectedDeviceId,
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001324 input_type_t *inputType)
Eric Laurente552edb2014-03-10 17:42:56 -07001325{
Eric Laurentcaf7f482014-11-25 17:50:47 -08001326 ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
1327 "session %d, flags %#x",
1328 attr->source, samplingRate, format, channelMask, session, flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001329
Eric Laurentcaf7f482014-11-25 17:50:47 -08001330 *input = AUDIO_IO_HANDLE_NONE;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001331 *inputType = API_INPUT_INVALID;
Eric Laurent275e8e92014-11-30 15:14:47 -08001332 audio_devices_t device;
1333 // handle legacy remote submix case where the address was not always specified
1334 String8 address = String8("");
Eric Laurent5dbe4712014-09-19 19:04:57 -07001335 bool isSoundTrigger = false;
Eric Laurentc447ded2015-01-06 08:47:05 -08001336 audio_source_t inputSource = attr->source;
1337 audio_source_t halInputSource;
Eric Laurentc722f302014-12-10 11:21:49 -08001338 AudioMix *policyMix = NULL;
Eric Laurent275e8e92014-11-30 15:14:47 -08001339
Eric Laurentc447ded2015-01-06 08:47:05 -08001340 if (inputSource == AUDIO_SOURCE_DEFAULT) {
1341 inputSource = AUDIO_SOURCE_MIC;
1342 }
1343 halInputSource = inputSource;
1344
Paul McLean466dc8e2015-04-17 13:15:36 -06001345 // Explicit routing?
1346 sp<DeviceDescriptor> deviceDesc;
1347 for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
1348 if (mAvailableInputDevices[i]->getId() == selectedDeviceId) {
1349 deviceDesc = mAvailableInputDevices[i];
1350 break;
1351 }
1352 }
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001353 mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
Paul McLean466dc8e2015-04-17 13:15:36 -06001354
Eric Laurentc447ded2015-01-06 08:47:05 -08001355 if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
Eric Laurent275e8e92014-11-30 15:14:47 -08001356 strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
Jean-Michel Trividacc06f2015-04-08 18:16:39 -07001357 status_t ret = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
François Gaffie036e1e92015-03-19 10:16:24 +01001358 if (ret != NO_ERROR) {
1359 return ret;
1360 }
1361 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
Eric Laurent275e8e92014-11-30 15:14:47 -08001362 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1363 address = String8(attr->tags + strlen("addr="));
Eric Laurent275e8e92014-11-30 15:14:47 -08001364 } else {
Eric Laurentc447ded2015-01-06 08:47:05 -08001365 device = getDeviceAndMixForInputSource(inputSource, &policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08001366 if (device == AUDIO_DEVICE_NONE) {
Eric Laurentc447ded2015-01-06 08:47:05 -08001367 ALOGW("getInputForAttr() could not find device for source %d", inputSource);
Eric Laurent275e8e92014-11-30 15:14:47 -08001368 return BAD_VALUE;
1369 }
Eric Laurentc722f302014-12-10 11:21:49 -08001370 if (policyMix != NULL) {
1371 address = policyMix->mRegistrationId;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001372 if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
1373 // there is an external policy, but this input is attached to a mix of recorders,
1374 // meaning it receives audio injected into the framework, so the recorder doesn't
1375 // know about it and is therefore considered "legacy"
1376 *inputType = API_INPUT_LEGACY;
1377 } else {
1378 // recording a mix of players defined by an external policy, we're rerouting for
1379 // an external policy
1380 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1381 }
Eric Laurentc722f302014-12-10 11:21:49 -08001382 } else if (audio_is_remote_submix_device(device)) {
1383 address = String8("0");
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001384 *inputType = API_INPUT_MIX_CAPTURE;
Eric Laurent82db2692015-08-07 13:59:42 -07001385 } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
1386 *inputType = API_INPUT_TELEPHONY_RX;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001387 } else {
1388 *inputType = API_INPUT_LEGACY;
Eric Laurentc722f302014-12-10 11:21:49 -08001389 }
Eric Laurent275e8e92014-11-30 15:14:47 -08001390 // adapt channel selection to input source
Eric Laurentc447ded2015-01-06 08:47:05 -08001391 switch (inputSource) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001392 case AUDIO_SOURCE_VOICE_UPLINK:
1393 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
1394 break;
1395 case AUDIO_SOURCE_VOICE_DOWNLINK:
1396 channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
1397 break;
1398 case AUDIO_SOURCE_VOICE_CALL:
1399 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
1400 break;
1401 default:
1402 break;
1403 }
Eric Laurentc447ded2015-01-06 08:47:05 -08001404 if (inputSource == AUDIO_SOURCE_HOTWORD) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001405 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1406 if (index >= 0) {
1407 *input = mSoundTriggerSessions.valueFor(session);
1408 isSoundTrigger = true;
1409 flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1410 ALOGV("SoundTrigger capture on session %d input %d", session, *input);
1411 } else {
1412 halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
1413 }
Eric Laurent5dbe4712014-09-19 19:04:57 -07001414 }
1415 }
1416
Andy Hungf129b032015-04-07 13:45:50 -07001417 // find a compatible input profile (not necessarily identical in parameters)
1418 sp<IOProfile> profile;
1419 // samplingRate and flags may be updated by getInputProfile
1420 uint32_t profileSamplingRate = samplingRate;
1421 audio_format_t profileFormat = format;
1422 audio_channel_mask_t profileChannelMask = channelMask;
1423 audio_input_flags_t profileFlags = flags;
1424 for (;;) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001425 profile = getInputProfile(device, address,
Andy Hungf129b032015-04-07 13:45:50 -07001426 profileSamplingRate, profileFormat, profileChannelMask,
1427 profileFlags);
1428 if (profile != 0) {
1429 break; // success
1430 } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
1431 profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
1432 } else { // fail
Eric Laurentcaf7f482014-11-25 17:50:47 -08001433 ALOGW("getInputForAttr() could not find profile for device 0x%X, samplingRate %u,"
1434 "format %#x, channelMask 0x%X, flags %#x",
Andy Hungf129b032015-04-07 13:45:50 -07001435 device, samplingRate, format, channelMask, flags);
Eric Laurentcaf7f482014-11-25 17:50:47 -08001436 return BAD_VALUE;
Eric Laurent5dbe4712014-09-19 19:04:57 -07001437 }
Eric Laurente552edb2014-03-10 17:42:56 -07001438 }
1439
Eric Laurent322b4d22015-04-03 15:57:54 -07001440 if (profile->getModuleHandle() == 0) {
1441 ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
Eric Laurentcaf7f482014-11-25 17:50:47 -08001442 return NO_INIT;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001443 }
1444
1445 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
Andy Hungf129b032015-04-07 13:45:50 -07001446 config.sample_rate = profileSamplingRate;
1447 config.channel_mask = profileChannelMask;
1448 config.format = profileFormat;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001449
Eric Laurent322b4d22015-04-03 15:57:54 -07001450 status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
Eric Laurentcaf7f482014-11-25 17:50:47 -08001451 input,
Eric Laurentcf2c0212014-07-25 16:20:43 -07001452 &config,
1453 &device,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07001454 address,
Eric Laurent1c9c2cc2014-08-28 19:37:25 -07001455 halInputSource,
Andy Hungf129b032015-04-07 13:45:50 -07001456 profileFlags);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001457
1458 // only accept input with the exact requested set of parameters
Eric Laurentcaf7f482014-11-25 17:50:47 -08001459 if (status != NO_ERROR || *input == AUDIO_IO_HANDLE_NONE ||
Andy Hungf129b032015-04-07 13:45:50 -07001460 (profileSamplingRate != config.sample_rate) ||
1461 (profileFormat != config.format) ||
1462 (profileChannelMask != config.channel_mask)) {
1463 ALOGW("getInputForAttr() failed opening input: samplingRate %d, format %d,"
1464 " channelMask %x",
Eric Laurentcf2c0212014-07-25 16:20:43 -07001465 samplingRate, format, channelMask);
Eric Laurentcaf7f482014-11-25 17:50:47 -08001466 if (*input != AUDIO_IO_HANDLE_NONE) {
1467 mpClientInterface->closeInput(*input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001468 }
Eric Laurentcaf7f482014-11-25 17:50:47 -08001469 return BAD_VALUE;
Eric Laurente552edb2014-03-10 17:42:56 -07001470 }
1471
Eric Laurent1f2f2232014-06-02 12:01:23 -07001472 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
Eric Laurentc447ded2015-01-06 08:47:05 -08001473 inputDesc->mInputSource = inputSource;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001474 inputDesc->mRefCount = 0;
1475 inputDesc->mOpenRefCount = 1;
Andy Hungf129b032015-04-07 13:45:50 -07001476 inputDesc->mSamplingRate = profileSamplingRate;
1477 inputDesc->mFormat = profileFormat;
1478 inputDesc->mChannelMask = profileChannelMask;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001479 inputDesc->mDevice = device;
Eric Laurentc722f302014-12-10 11:21:49 -08001480 inputDesc->mSessions.add(session);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001481 inputDesc->mIsSoundTrigger = isSoundTrigger;
Eric Laurentc722f302014-12-10 11:21:49 -08001482 inputDesc->mPolicyMix = policyMix;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001483
Jean-Michel Trividacc06f2015-04-08 18:16:39 -07001484 ALOGV("getInputForAttr() returns input type = %d", *inputType);
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001485
Eric Laurentcaf7f482014-11-25 17:50:47 -08001486 addInput(*input, inputDesc);
Eric Laurentb52c1522014-05-20 11:27:36 -07001487 mpClientInterface->onAudioPortListUpdate();
Paul McLean466dc8e2015-04-17 13:15:36 -06001488
Eric Laurentcaf7f482014-11-25 17:50:47 -08001489 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07001490}
1491
Eric Laurent4dc68062014-07-28 17:26:49 -07001492status_t AudioPolicyManager::startInput(audio_io_handle_t input,
1493 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001494{
1495 ALOGV("startInput() input %d", input);
1496 ssize_t index = mInputs.indexOfKey(input);
1497 if (index < 0) {
1498 ALOGW("startInput() unknown input %d", input);
1499 return BAD_VALUE;
1500 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001501 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001502
Eric Laurentc722f302014-12-10 11:21:49 -08001503 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001504 if (index < 0) {
1505 ALOGW("startInput() unknown session %d on input %d", session, input);
1506 return BAD_VALUE;
1507 }
1508
Glenn Kasten74a8e252014-07-24 14:09:55 -07001509 // virtual input devices are compatible with other input devices
François Gaffie53615e22015-03-19 09:24:12 +01001510 if (!is_virtual_input_device(inputDesc->mDevice)) {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001511
1512 // for a non-virtual input device, check if there is another (non-virtual) active input
François Gaffie53615e22015-03-19 09:24:12 +01001513 audio_io_handle_t activeInput = mInputs.getActiveInput();
Glenn Kasten74a8e252014-07-24 14:09:55 -07001514 if (activeInput != 0 && activeInput != input) {
1515
1516 // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1517 // otherwise the active input continues and the new input cannot be started.
Eric Laurent1f2f2232014-06-02 12:01:23 -07001518 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
Eric Laurent64265b22015-09-18 18:32:07 -07001519 if ((activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) &&
1520 !activeDesc->hasPreemptedSession(session)) {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001521 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
Eric Laurent64265b22015-09-18 18:32:07 -07001522 audio_session_t activeSession = activeDesc->mSessions.itemAt(0);
1523 SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
1524 sessions.add(activeSession);
1525 inputDesc->setPreemptedSessions(sessions);
1526 stopInput(activeInput, activeSession);
1527 releaseInput(activeInput, activeSession);
Eric Laurente552edb2014-03-10 17:42:56 -07001528 } else {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001529 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
Eric Laurente552edb2014-03-10 17:42:56 -07001530 return INVALID_OPERATION;
1531 }
1532 }
Eric Laurentc0a889f2015-10-14 14:36:34 -07001533
1534 // Do not allow capture if an active voice call is using a software patch and
1535 // the call TX source device is on the same HW module.
1536 // FIXME: would be better to refine to only inputs whose profile connects to the
1537 // call TX device but this information is not in the audio patch
1538 if (mCallTxPatch != 0 &&
1539 inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1540 return INVALID_OPERATION;
1541 }
Eric Laurente552edb2014-03-10 17:42:56 -07001542 }
1543
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001544 // Routing?
1545 mInputRoutes.incRouteActivity(session);
1546
Paul McLean466dc8e2015-04-17 13:15:36 -06001547 if (inputDesc->mRefCount == 0 || mInputRoutes.hasRouteChanged(session)) {
Jean-Michel Trivi2b0c1fc2015-04-15 17:29:28 -07001548 // if input maps to a dynamic policy with an activity listener, notify of state change
1549 if ((inputDesc->mPolicyMix != NULL)
Jean-Michel Trivif613d422015-04-23 18:41:29 -07001550 && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
Jean-Michel Trivi2b0c1fc2015-04-15 17:29:28 -07001551 mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
1552 MIX_STATE_MIXING);
1553 }
1554
François Gaffie53615e22015-03-19 09:24:12 +01001555 if (mInputs.activeInputsCount() == 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001556 SoundTrigger::setCaptureState(true);
1557 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001558 setInputDevice(input, getNewInputDevice(input), true /* force */);
Eric Laurente552edb2014-03-10 17:42:56 -07001559
Eric Laurentc722f302014-12-10 11:21:49 -08001560 // automatically enable the remote submix output when input is started if not
1561 // used by a policy mix of type MIX_TYPE_RECORDERS
Glenn Kasten74a8e252014-07-24 14:09:55 -07001562 // For remote submix (a virtual device), we open only one input per capture request.
1563 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
Eric Laurentc722f302014-12-10 11:21:49 -08001564 String8 address = String8("");
1565 if (inputDesc->mPolicyMix == NULL) {
1566 address = String8("0");
1567 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1568 address = inputDesc->mPolicyMix->mRegistrationId;
1569 }
1570 if (address != "") {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001571 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001572 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001573 address, "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001574 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001575 }
Eric Laurente552edb2014-03-10 17:42:56 -07001576 }
1577
Eric Laurente552edb2014-03-10 17:42:56 -07001578 ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1579
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001580 inputDesc->mRefCount++;
Eric Laurente552edb2014-03-10 17:42:56 -07001581 return NO_ERROR;
1582}
1583
Eric Laurent4dc68062014-07-28 17:26:49 -07001584status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
1585 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001586{
1587 ALOGV("stopInput() input %d", input);
1588 ssize_t index = mInputs.indexOfKey(input);
1589 if (index < 0) {
1590 ALOGW("stopInput() unknown input %d", input);
1591 return BAD_VALUE;
1592 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001593 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001594
Eric Laurentc722f302014-12-10 11:21:49 -08001595 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001596 if (index < 0) {
1597 ALOGW("stopInput() unknown session %d on input %d", session, input);
1598 return BAD_VALUE;
1599 }
1600
Eric Laurente552edb2014-03-10 17:42:56 -07001601 if (inputDesc->mRefCount == 0) {
1602 ALOGW("stopInput() input %d already stopped", input);
1603 return INVALID_OPERATION;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001604 }
1605
1606 inputDesc->mRefCount--;
Paul McLean466dc8e2015-04-17 13:15:36 -06001607
1608 // Routing?
1609 mInputRoutes.decRouteActivity(session);
1610
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001611 if (inputDesc->mRefCount == 0) {
Jean-Michel Trivi2b0c1fc2015-04-15 17:29:28 -07001612 // if input maps to a dynamic policy with an activity listener, notify of state change
1613 if ((inputDesc->mPolicyMix != NULL)
Jean-Michel Trivif613d422015-04-23 18:41:29 -07001614 && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
Jean-Michel Trivi2b0c1fc2015-04-15 17:29:28 -07001615 mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
1616 MIX_STATE_IDLE);
1617 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001618
Eric Laurentc722f302014-12-10 11:21:49 -08001619 // automatically disable the remote submix output when input is stopped if not
1620 // used by a policy mix of type MIX_TYPE_RECORDERS
Eric Laurente552edb2014-03-10 17:42:56 -07001621 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
Eric Laurentc722f302014-12-10 11:21:49 -08001622 String8 address = String8("");
1623 if (inputDesc->mPolicyMix == NULL) {
1624 address = String8("0");
1625 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1626 address = inputDesc->mPolicyMix->mRegistrationId;
1627 }
1628 if (address != "") {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001629 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001630 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001631 address, "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001632 }
Eric Laurente552edb2014-03-10 17:42:56 -07001633 }
1634
Eric Laurent1c333e22014-05-20 10:48:17 -07001635 resetInputDevice(input);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001636
François Gaffie53615e22015-03-19 09:24:12 +01001637 if (mInputs.activeInputsCount() == 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001638 SoundTrigger::setCaptureState(false);
1639 }
Eric Laurent64265b22015-09-18 18:32:07 -07001640 inputDesc->clearPreemptedSessions();
Eric Laurente552edb2014-03-10 17:42:56 -07001641 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001642 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07001643}
1644
Eric Laurent4dc68062014-07-28 17:26:49 -07001645void AudioPolicyManager::releaseInput(audio_io_handle_t input,
1646 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001647{
1648 ALOGV("releaseInput() %d", input);
1649 ssize_t index = mInputs.indexOfKey(input);
1650 if (index < 0) {
1651 ALOGW("releaseInput() releasing unknown input %d", input);
1652 return;
1653 }
Paul McLean466dc8e2015-04-17 13:15:36 -06001654
1655 // Routing
1656 mInputRoutes.removeRoute(session);
1657
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001658 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1659 ALOG_ASSERT(inputDesc != 0);
Eric Laurent4dc68062014-07-28 17:26:49 -07001660
Eric Laurentc722f302014-12-10 11:21:49 -08001661 index = inputDesc->mSessions.indexOf(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07001662 if (index < 0) {
1663 ALOGW("releaseInput() unknown session %d on input %d", session, input);
1664 return;
1665 }
Eric Laurentc722f302014-12-10 11:21:49 -08001666 inputDesc->mSessions.remove(session);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001667 if (inputDesc->mOpenRefCount == 0) {
1668 ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
1669 return;
1670 }
1671 inputDesc->mOpenRefCount--;
1672 if (inputDesc->mOpenRefCount > 0) {
1673 ALOGV("releaseInput() exit > 0");
1674 return;
1675 }
1676
Eric Laurent05b90f82014-08-27 15:32:29 -07001677 closeInput(input);
Eric Laurentb52c1522014-05-20 11:27:36 -07001678 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001679 ALOGV("releaseInput() exit");
1680}
1681
Eric Laurentd4692962014-05-05 18:13:44 -07001682void AudioPolicyManager::closeAllInputs() {
Eric Laurent05b90f82014-08-27 15:32:29 -07001683 bool patchRemoved = false;
1684
Eric Laurentd4692962014-05-05 18:13:44 -07001685 for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
Eric Laurent05b90f82014-08-27 15:32:29 -07001686 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
1687 ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
1688 if (patch_index >= 0) {
1689 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
1690 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
1691 mAudioPatches.removeItemsAt(patch_index);
1692 patchRemoved = true;
1693 }
Eric Laurentd4692962014-05-05 18:13:44 -07001694 mpClientInterface->closeInput(mInputs.keyAt(input_index));
1695 }
1696 mInputs.clear();
Eric Laurent6a94d692014-05-20 11:18:06 -07001697 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07001698
1699 if (patchRemoved) {
1700 mpClientInterface->onAudioPatchListUpdate();
1701 }
Eric Laurentd4692962014-05-05 18:13:44 -07001702}
1703
Eric Laurente0720872014-03-11 09:30:41 -07001704void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001705 int indexMin,
1706 int indexMax)
1707{
1708 ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
François Gaffie2110e042015-03-24 08:41:51 +01001709 mEngine->initStreamVolume(stream, indexMin, indexMax);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001710 //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
1711 if (stream == AUDIO_STREAM_MUSIC) {
François Gaffie2110e042015-03-24 08:41:51 +01001712 mEngine->initStreamVolume(AUDIO_STREAM_ACCESSIBILITY, indexMin, indexMax);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001713 }
Eric Laurente552edb2014-03-10 17:42:56 -07001714}
1715
Eric Laurente0720872014-03-11 09:30:41 -07001716status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01001717 int index,
1718 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07001719{
1720
Eric Laurentc75307b2015-03-17 15:29:32 -07001721 if ((index < mStreams.valueFor(stream).getVolumeIndexMin()) ||
1722 (index > mStreams.valueFor(stream).getVolumeIndexMax())) {
Eric Laurente552edb2014-03-10 17:42:56 -07001723 return BAD_VALUE;
1724 }
1725 if (!audio_is_output_device(device)) {
1726 return BAD_VALUE;
1727 }
1728
1729 // Force max volume if stream cannot be muted
Eric Laurentc75307b2015-03-17 15:29:32 -07001730 if (!mStreams.canBeMuted(stream)) index = mStreams.valueFor(stream).getVolumeIndexMax();
Eric Laurente552edb2014-03-10 17:42:56 -07001731
1732 ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1733 stream, device, index);
1734
1735 // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1736 // clear all device specific values
1737 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
François Gaffiedfd74092015-03-19 12:10:59 +01001738 mStreams.clearCurrentVolumeIndex(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07001739 }
François Gaffiedfd74092015-03-19 12:10:59 +01001740 mStreams.addCurrentVolumeIndex(stream, device, index);
Eric Laurente552edb2014-03-10 17:42:56 -07001741
Eric Laurent31551f82014-10-10 18:21:56 -07001742 // update volume on all outputs whose current device is also selected by the same
1743 // strategy as the device specified by the caller
1744 audio_devices_t strategyDevice = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001745
1746
1747 //FIXME: AUDIO_STREAM_ACCESSIBILITY volume follows AUDIO_STREAM_MUSIC for now
1748 audio_devices_t accessibilityDevice = AUDIO_DEVICE_NONE;
1749 if (stream == AUDIO_STREAM_MUSIC) {
François Gaffiedfd74092015-03-19 12:10:59 +01001750 mStreams.addCurrentVolumeIndex(AUDIO_STREAM_ACCESSIBILITY, device, index);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001751 accessibilityDevice = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, true /*fromCache*/);
1752 }
1753 if ((device != AUDIO_DEVICE_OUT_DEFAULT) &&
1754 (device & (strategyDevice | accessibilityDevice)) == 0) {
Eric Laurent31551f82014-10-10 18:21:56 -07001755 return NO_ERROR;
1756 }
Eric Laurente552edb2014-03-10 17:42:56 -07001757 status_t status = NO_ERROR;
1758 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001759 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
1760 audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
Eric Laurent31551f82014-10-10 18:21:56 -07001761 if ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & strategyDevice) != 0)) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001762 status_t volStatus = checkAndSetVolume(stream, index, desc, curDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07001763 if (volStatus != NO_ERROR) {
1764 status = volStatus;
1765 }
1766 }
Jean-Michel Triviaf20bc22015-09-14 16:37:07 -07001767 if ((accessibilityDevice != AUDIO_DEVICE_NONE) &&
1768 ((device == AUDIO_DEVICE_OUT_DEFAULT) || ((curDevice & accessibilityDevice) != 0)))
1769 {
Eric Laurent223fd5c2014-11-11 13:43:36 -08001770 status_t volStatus = checkAndSetVolume(AUDIO_STREAM_ACCESSIBILITY,
Eric Laurentc75307b2015-03-17 15:29:32 -07001771 index, desc, curDevice);
Eric Laurent223fd5c2014-11-11 13:43:36 -08001772 }
Eric Laurente552edb2014-03-10 17:42:56 -07001773 }
1774 return status;
1775}
1776
Eric Laurente0720872014-03-11 09:30:41 -07001777status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001778 int *index,
1779 audio_devices_t device)
1780{
1781 if (index == NULL) {
1782 return BAD_VALUE;
1783 }
1784 if (!audio_is_output_device(device)) {
1785 return BAD_VALUE;
1786 }
1787 // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
1788 // the strategy the stream belongs to.
1789 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1790 device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1791 }
François Gaffiedfd74092015-03-19 12:10:59 +01001792 device = Volume::getDeviceForVolume(device);
Eric Laurente552edb2014-03-10 17:42:56 -07001793
Eric Laurentc75307b2015-03-17 15:29:32 -07001794 *index = mStreams.valueFor(stream).getVolumeIndex(device);
Eric Laurente552edb2014-03-10 17:42:56 -07001795 ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1796 return NO_ERROR;
1797}
1798
Eric Laurente0720872014-03-11 09:30:41 -07001799audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
Eric Laurente552edb2014-03-10 17:42:56 -07001800 const SortedVector<audio_io_handle_t>& outputs)
1801{
1802 // select one output among several suitable for global effects.
1803 // The priority is as follows:
1804 // 1: An offloaded output. If the effect ends up not being offloadable,
1805 // AudioFlinger will invalidate the track and the offloaded output
1806 // will be closed causing the effect to be moved to a PCM output.
1807 // 2: A deep buffer output
1808 // 3: the first output in the list
1809
1810 if (outputs.size() == 0) {
1811 return 0;
1812 }
1813
1814 audio_io_handle_t outputOffloaded = 0;
1815 audio_io_handle_t outputDeepBuffer = 0;
1816
1817 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001818 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurentd4692962014-05-05 18:13:44 -07001819 ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -07001820 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1821 outputOffloaded = outputs[i];
1822 }
1823 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1824 outputDeepBuffer = outputs[i];
1825 }
1826 }
1827
1828 ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
1829 outputOffloaded, outputDeepBuffer);
1830 if (outputOffloaded != 0) {
1831 return outputOffloaded;
1832 }
1833 if (outputDeepBuffer != 0) {
1834 return outputDeepBuffer;
1835 }
1836
1837 return outputs[0];
1838}
1839
Eric Laurente0720872014-03-11 09:30:41 -07001840audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
Eric Laurente552edb2014-03-10 17:42:56 -07001841{
1842 // apply simple rule where global effects are attached to the same output as MUSIC streams
1843
Eric Laurent3b73df72014-03-11 09:06:29 -07001844 routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
Eric Laurente552edb2014-03-10 17:42:56 -07001845 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
1846 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
1847
1848 audio_io_handle_t output = selectOutputForEffects(dstOutputs);
1849 ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
1850 output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags);
1851
1852 return output;
1853}
1854
Eric Laurente0720872014-03-11 09:30:41 -07001855status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
Eric Laurente552edb2014-03-10 17:42:56 -07001856 audio_io_handle_t io,
1857 uint32_t strategy,
1858 int session,
1859 int id)
1860{
1861 ssize_t index = mOutputs.indexOfKey(io);
1862 if (index < 0) {
1863 index = mInputs.indexOfKey(io);
1864 if (index < 0) {
1865 ALOGW("registerEffect() unknown io %d", io);
1866 return INVALID_OPERATION;
1867 }
1868 }
François Gaffie45ed3b02015-03-19 10:35:14 +01001869 return mEffects.registerEffect(desc, io, strategy, session, id);
Eric Laurente552edb2014-03-10 17:42:56 -07001870}
1871
Eric Laurentc75307b2015-03-17 15:29:32 -07001872bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
1873{
1874 return mOutputs.isStreamActive(stream, inPastMs);
1875}
1876
1877bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
1878{
1879 return mOutputs.isStreamActiveRemotely(stream, inPastMs);
1880}
1881
Eric Laurente0720872014-03-11 09:30:41 -07001882bool AudioPolicyManager::isSourceActive(audio_source_t source) const
Eric Laurente552edb2014-03-10 17:42:56 -07001883{
1884 for (size_t i = 0; i < mInputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001885 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
Eric Laurenta34c9ce2014-12-19 11:16:32 -08001886 if (inputDescriptor->mRefCount == 0) {
1887 continue;
1888 }
1889 if (inputDescriptor->mInputSource == (int)source) {
Eric Laurente552edb2014-03-10 17:42:56 -07001890 return true;
1891 }
Eric Laurenta34c9ce2014-12-19 11:16:32 -08001892 // AUDIO_SOURCE_HOTWORD is equivalent to AUDIO_SOURCE_VOICE_RECOGNITION only if it
1893 // corresponds to an active capture triggered by a hardware hotword recognition
1894 if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) &&
1895 (inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD)) {
1896 // FIXME: we should not assume that the first session is the active one and keep
1897 // activity count per session. Same in startInput().
1898 ssize_t index = mSoundTriggerSessions.indexOfKey(inputDescriptor->mSessions.itemAt(0));
1899 if (index >= 0) {
1900 return true;
1901 }
1902 }
Eric Laurente552edb2014-03-10 17:42:56 -07001903 }
1904 return false;
1905}
1906
Eric Laurent275e8e92014-11-30 15:14:47 -08001907// Register a list of custom mixes with their attributes and format.
1908// When a mix is registered, corresponding input and output profiles are
1909// added to the remote submix hw module. The profile contains only the
1910// parameters (sampling rate, format...) specified by the mix.
1911// The corresponding input remote submix device is also connected.
1912//
1913// When a remote submix device is connected, the address is checked to select the
1914// appropriate profile and the corresponding input or output stream is opened.
1915//
1916// When capture starts, getInputForAttr() will:
1917// - 1 look for a mix matching the address passed in attribtutes tags if any
1918// - 2 if none found, getDeviceForInputSource() will:
1919// - 2.1 look for a mix matching the attributes source
1920// - 2.2 if none found, default to device selection by policy rules
1921// At this time, the corresponding output remote submix device is also connected
1922// and active playback use cases can be transferred to this mix if needed when reconnecting
1923// after AudioTracks are invalidated
1924//
1925// When playback starts, getOutputForAttr() will:
1926// - 1 look for a mix matching the address passed in attribtutes tags if any
1927// - 2 if none found, look for a mix matching the attributes usage
1928// - 3 if none found, default to device and output selection by policy rules.
1929
1930status_t AudioPolicyManager::registerPolicyMixes(Vector<AudioMix> mixes)
1931{
1932 sp<HwModule> module;
1933 for (size_t i = 0; i < mHwModules.size(); i++) {
1934 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 &&
1935 mHwModules[i]->mHandle != 0) {
1936 module = mHwModules[i];
1937 break;
1938 }
1939 }
1940
1941 if (module == 0) {
1942 return INVALID_OPERATION;
1943 }
1944
1945 ALOGV("registerPolicyMixes() num mixes %d", mixes.size());
1946
1947 for (size_t i = 0; i < mixes.size(); i++) {
1948 String8 address = mixes[i].mRegistrationId;
François Gaffie036e1e92015-03-19 10:16:24 +01001949
1950 if (mPolicyMixes.registerMix(address, mixes[i]) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001951 continue;
1952 }
1953 audio_config_t outputConfig = mixes[i].mFormat;
1954 audio_config_t inputConfig = mixes[i].mFormat;
1955 // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
1956 // stereo and let audio flinger do the channel conversion if needed.
1957 outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
1958 inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
1959 module->addOutputProfile(address, &outputConfig,
1960 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
1961 module->addInputProfile(address, &inputConfig,
1962 AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
François Gaffie036e1e92015-03-19 10:16:24 +01001963
Eric Laurentc722f302014-12-10 11:21:49 -08001964 if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001965 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001966 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001967 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001968 } else {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08001969 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08001970 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08001971 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08001972 }
Eric Laurent275e8e92014-11-30 15:14:47 -08001973 }
1974 return NO_ERROR;
1975}
1976
1977status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
1978{
1979 sp<HwModule> module;
1980 for (size_t i = 0; i < mHwModules.size(); i++) {
1981 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[i]->mName) == 0 &&
1982 mHwModules[i]->mHandle != 0) {
1983 module = mHwModules[i];
1984 break;
1985 }
1986 }
1987
1988 if (module == 0) {
1989 return INVALID_OPERATION;
1990 }
1991
1992 ALOGV("unregisterPolicyMixes() num mixes %d", mixes.size());
1993
1994 for (size_t i = 0; i < mixes.size(); i++) {
1995 String8 address = mixes[i].mRegistrationId;
François Gaffie036e1e92015-03-19 10:16:24 +01001996
1997 if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001998 continue;
1999 }
2000
Eric Laurentc722f302014-12-10 11:21:49 -08002001 if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
2002 AUDIO_POLICY_DEVICE_STATE_AVAILABLE)
2003 {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08002004 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
Eric Laurentc722f302014-12-10 11:21:49 -08002005 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08002006 address.string(), "remote-submix");
Eric Laurentc722f302014-12-10 11:21:49 -08002007 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002008
2009 if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
2010 AUDIO_POLICY_DEVICE_STATE_AVAILABLE)
2011 {
Eric Laurentc73ca6e2014-12-12 14:34:22 -08002012 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurent275e8e92014-11-30 15:14:47 -08002013 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Paul McLeane743a472015-01-28 11:07:31 -08002014 address.string(), "remote-submix");
Eric Laurent275e8e92014-11-30 15:14:47 -08002015 }
2016 module->removeOutputProfile(address);
2017 module->removeInputProfile(address);
2018 }
2019 return NO_ERROR;
2020}
2021
Eric Laurente552edb2014-03-10 17:42:56 -07002022
Eric Laurente0720872014-03-11 09:30:41 -07002023status_t AudioPolicyManager::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07002024{
2025 const size_t SIZE = 256;
2026 char buffer[SIZE];
2027 String8 result;
2028
2029 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
2030 result.append(buffer);
2031
Eric Laurent87ffa392015-05-22 10:32:38 -07002032 snprintf(buffer, SIZE, " Primary Output: %d\n",
2033 hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
Eric Laurente552edb2014-03-10 17:42:56 -07002034 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002035 snprintf(buffer, SIZE, " Phone state: %d\n", mEngine->getPhoneState());
Eric Laurente552edb2014-03-10 17:42:56 -07002036 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07002037 snprintf(buffer, SIZE, " Force use for communications %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01002038 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
Eric Laurente552edb2014-03-10 17:42:56 -07002039 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002040 snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
Eric Laurente552edb2014-03-10 17:42:56 -07002041 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002042 snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
Eric Laurente552edb2014-03-10 17:42:56 -07002043 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002044 snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
Eric Laurente552edb2014-03-10 17:42:56 -07002045 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002046 snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
Eric Laurente552edb2014-03-10 17:42:56 -07002047 result.append(buffer);
Jungshik Jang7b24ee32014-07-15 19:38:42 +09002048 snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01002049 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
Jungshik Jang7b24ee32014-07-15 19:38:42 +09002050 result.append(buffer);
Eric Laurent9459fb02015-08-12 18:36:32 -07002051 snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
2052 result.append(buffer);
2053
François Gaffie2110e042015-03-24 08:41:51 +01002054 write(fd, result.string(), result.size());
Eric Laurente552edb2014-03-10 17:42:56 -07002055
François Gaffie53615e22015-03-19 09:24:12 +01002056 mAvailableOutputDevices.dump(fd, String8("output"));
2057 mAvailableInputDevices.dump(fd, String8("input"));
2058 mHwModules.dump(fd);
2059 mOutputs.dump(fd);
2060 mInputs.dump(fd);
François Gaffiedfd74092015-03-19 12:10:59 +01002061 mStreams.dump(fd);
François Gaffie45ed3b02015-03-19 10:35:14 +01002062 mEffects.dump(fd);
François Gaffie53615e22015-03-19 09:24:12 +01002063 mAudioPatches.dump(fd);
Eric Laurente552edb2014-03-10 17:42:56 -07002064
2065 return NO_ERROR;
2066}
2067
2068// This function checks for the parameters which can be offloaded.
2069// This can be enhanced depending on the capability of the DSP and policy
2070// of the system.
Eric Laurente0720872014-03-11 09:30:41 -07002071bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -07002072{
2073 ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
Eric Laurentd4692962014-05-05 18:13:44 -07002074 " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
Eric Laurente552edb2014-03-10 17:42:56 -07002075 offloadInfo.sample_rate, offloadInfo.channel_mask,
2076 offloadInfo.format,
2077 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
2078 offloadInfo.has_video);
2079
2080 // Check if offload has been disabled
2081 char propValue[PROPERTY_VALUE_MAX];
2082 if (property_get("audio.offload.disable", propValue, "0")) {
2083 if (atoi(propValue) != 0) {
2084 ALOGV("offload disabled by audio.offload.disable=%s", propValue );
2085 return false;
2086 }
2087 }
2088
2089 // Check if stream type is music, then only allow offload as of now.
2090 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
2091 {
2092 ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
2093 return false;
2094 }
2095
2096 //TODO: enable audio offloading with video when ready
Andy Hung08945c42015-05-31 21:36:46 -07002097 const bool allowOffloadWithVideo =
2098 property_get_bool("audio.offload.video", false /* default_value */);
2099 if (offloadInfo.has_video && !allowOffloadWithVideo) {
Eric Laurente552edb2014-03-10 17:42:56 -07002100 ALOGV("isOffloadSupported: has_video == true, returning false");
2101 return false;
2102 }
2103
2104 //If duration is less than minimum value defined in property, return false
2105 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
2106 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
2107 ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
2108 return false;
2109 }
2110 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
2111 ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
2112 return false;
2113 }
2114
2115 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
2116 // creating an offloaded track and tearing it down immediately after start when audioflinger
2117 // detects there is an active non offloadable effect.
2118 // FIXME: We should check the audio session here but we do not have it in this context.
2119 // This may prevent offloading in rare situations where effects are left active by apps
2120 // in the background.
François Gaffie45ed3b02015-03-19 10:35:14 +01002121 if (mEffects.isNonOffloadableEffectEnabled()) {
Eric Laurente552edb2014-03-10 17:42:56 -07002122 return false;
2123 }
2124
2125 // See if there is a profile to support this.
2126 // AUDIO_DEVICE_NONE
Eric Laurent1c333e22014-05-20 10:48:17 -07002127 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Eric Laurente552edb2014-03-10 17:42:56 -07002128 offloadInfo.sample_rate,
2129 offloadInfo.format,
2130 offloadInfo.channel_mask,
2131 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Eric Laurent1c333e22014-05-20 10:48:17 -07002132 ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
2133 return (profile != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07002134}
2135
Eric Laurent6a94d692014-05-20 11:18:06 -07002136status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
2137 audio_port_type_t type,
2138 unsigned int *num_ports,
2139 struct audio_port *ports,
2140 unsigned int *generation)
2141{
2142 if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
2143 generation == NULL) {
2144 return BAD_VALUE;
2145 }
2146 ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
2147 if (ports == NULL) {
2148 *num_ports = 0;
2149 }
2150
2151 size_t portsWritten = 0;
2152 size_t portsMax = *num_ports;
2153 *num_ports = 0;
2154 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
2155 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
2156 for (size_t i = 0;
2157 i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
2158 mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
2159 }
2160 *num_ports += mAvailableOutputDevices.size();
2161 }
2162 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
2163 for (size_t i = 0;
2164 i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
2165 mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
2166 }
2167 *num_ports += mAvailableInputDevices.size();
2168 }
2169 }
2170 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
2171 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
2172 for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
2173 mInputs[i]->toAudioPort(&ports[portsWritten++]);
2174 }
2175 *num_ports += mInputs.size();
2176 }
2177 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent84c70242014-06-23 08:46:27 -07002178 size_t numOutputs = 0;
2179 for (size_t i = 0; i < mOutputs.size(); i++) {
2180 if (!mOutputs[i]->isDuplicated()) {
2181 numOutputs++;
2182 if (portsWritten < portsMax) {
2183 mOutputs[i]->toAudioPort(&ports[portsWritten++]);
2184 }
2185 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002186 }
Eric Laurent84c70242014-06-23 08:46:27 -07002187 *num_ports += numOutputs;
Eric Laurent6a94d692014-05-20 11:18:06 -07002188 }
2189 }
2190 *generation = curAudioPortGeneration();
Mark Salyzynbeb9e302014-06-18 16:33:15 -07002191 ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
Eric Laurent6a94d692014-05-20 11:18:06 -07002192 return NO_ERROR;
2193}
2194
2195status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
2196{
2197 return NO_ERROR;
2198}
2199
Eric Laurent6a94d692014-05-20 11:18:06 -07002200status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
2201 audio_patch_handle_t *handle,
2202 uid_t uid)
2203{
2204 ALOGV("createAudioPatch()");
2205
2206 if (handle == NULL || patch == NULL) {
2207 return BAD_VALUE;
2208 }
2209 ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
2210
Eric Laurent874c42872014-08-08 15:13:39 -07002211 if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2212 patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2213 return BAD_VALUE;
2214 }
2215 // only one source per audio patch supported for now
2216 if (patch->num_sources > 1) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002217 return INVALID_OPERATION;
2218 }
Eric Laurent874c42872014-08-08 15:13:39 -07002219
2220 if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002221 return INVALID_OPERATION;
2222 }
Eric Laurent874c42872014-08-08 15:13:39 -07002223 for (size_t i = 0; i < patch->num_sinks; i++) {
2224 if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2225 return INVALID_OPERATION;
2226 }
2227 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002228
2229 sp<AudioPatch> patchDesc;
2230 ssize_t index = mAudioPatches.indexOfKey(*handle);
2231
Eric Laurent6a94d692014-05-20 11:18:06 -07002232 ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
2233 patch->sources[0].role,
2234 patch->sources[0].type);
Eric Laurent874c42872014-08-08 15:13:39 -07002235#if LOG_NDEBUG == 0
2236 for (size_t i = 0; i < patch->num_sinks; i++) {
2237 ALOGV("createAudioPatch sink %d: id %d role %d type %d", i, patch->sinks[i].id,
2238 patch->sinks[i].role,
2239 patch->sinks[i].type);
2240 }
2241#endif
Eric Laurent6a94d692014-05-20 11:18:06 -07002242
2243 if (index >= 0) {
2244 patchDesc = mAudioPatches.valueAt(index);
2245 ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2246 mUidCached, patchDesc->mUid, uid);
2247 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2248 return INVALID_OPERATION;
2249 }
2250 } else {
2251 *handle = 0;
2252 }
2253
2254 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002255 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002256 if (outputDesc == NULL) {
2257 ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
2258 return BAD_VALUE;
2259 }
Eric Laurent84c70242014-06-23 08:46:27 -07002260 ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
2261 outputDesc->mIoHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002262 if (patchDesc != 0) {
2263 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
2264 ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
2265 patchDesc->mPatch.sources[0].id, patch->sources[0].id);
2266 return BAD_VALUE;
2267 }
2268 }
Eric Laurent874c42872014-08-08 15:13:39 -07002269 DeviceVector devices;
2270 for (size_t i = 0; i < patch->num_sinks; i++) {
2271 // Only support mix to devices connection
2272 // TODO add support for mix to mix connection
2273 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2274 ALOGV("createAudioPatch() source mix but sink is not a device");
2275 return INVALID_OPERATION;
2276 }
2277 sp<DeviceDescriptor> devDesc =
2278 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2279 if (devDesc == 0) {
2280 ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2281 return BAD_VALUE;
2282 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002283
François Gaffie53615e22015-03-19 09:24:12 +01002284 if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002285 devDesc->mAddress,
Eric Laurent874c42872014-08-08 15:13:39 -07002286 patch->sources[0].sample_rate,
François Gaffie53615e22015-03-19 09:24:12 +01002287 NULL, // updatedSamplingRate
2288 patch->sources[0].format,
Andy Hungf129b032015-04-07 13:45:50 -07002289 NULL, // updatedFormat
François Gaffie53615e22015-03-19 09:24:12 +01002290 patch->sources[0].channel_mask,
Andy Hungf129b032015-04-07 13:45:50 -07002291 NULL, // updatedChannelMask
François Gaffie53615e22015-03-19 09:24:12 +01002292 AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
Andy Hungf129b032015-04-07 13:45:50 -07002293 ALOGV("createAudioPatch() profile not supported for device %08x",
2294 devDesc->type());
Eric Laurent874c42872014-08-08 15:13:39 -07002295 return INVALID_OPERATION;
2296 }
2297 devices.add(devDesc);
2298 }
2299 if (devices.size() == 0) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002300 return INVALID_OPERATION;
2301 }
Eric Laurent874c42872014-08-08 15:13:39 -07002302
Eric Laurent6a94d692014-05-20 11:18:06 -07002303 // TODO: reconfigure output format and channels here
2304 ALOGV("createAudioPatch() setting device %08x on output %d",
Eric Laurent874c42872014-08-08 15:13:39 -07002305 devices.types(), outputDesc->mIoHandle);
Eric Laurentc75307b2015-03-17 15:29:32 -07002306 setOutputDevice(outputDesc, devices.types(), true, 0, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002307 index = mAudioPatches.indexOfKey(*handle);
2308 if (index >= 0) {
2309 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2310 ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
2311 }
2312 patchDesc = mAudioPatches.valueAt(index);
2313 patchDesc->mUid = uid;
2314 ALOGV("createAudioPatch() success");
2315 } else {
2316 ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
2317 return INVALID_OPERATION;
2318 }
2319 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2320 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
2321 // input device to input mix connection
Eric Laurent874c42872014-08-08 15:13:39 -07002322 // only one sink supported when connecting an input device to a mix
2323 if (patch->num_sinks > 1) {
2324 return INVALID_OPERATION;
2325 }
François Gaffie53615e22015-03-19 09:24:12 +01002326 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002327 if (inputDesc == NULL) {
2328 return BAD_VALUE;
2329 }
2330 if (patchDesc != 0) {
2331 if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
2332 return BAD_VALUE;
2333 }
2334 }
2335 sp<DeviceDescriptor> devDesc =
2336 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
2337 if (devDesc == 0) {
2338 return BAD_VALUE;
2339 }
2340
François Gaffie53615e22015-03-19 09:24:12 +01002341 if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002342 devDesc->mAddress,
2343 patch->sinks[0].sample_rate,
2344 NULL, /*updatedSampleRate*/
2345 patch->sinks[0].format,
Andy Hungf129b032015-04-07 13:45:50 -07002346 NULL, /*updatedFormat*/
Eric Laurent275e8e92014-11-30 15:14:47 -08002347 patch->sinks[0].channel_mask,
Andy Hungf129b032015-04-07 13:45:50 -07002348 NULL, /*updatedChannelMask*/
Eric Laurent275e8e92014-11-30 15:14:47 -08002349 // FIXME for the parameter type,
2350 // and the NONE
2351 (audio_output_flags_t)
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002352 AUDIO_INPUT_FLAG_NONE)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002353 return INVALID_OPERATION;
2354 }
2355 // TODO: reconfigure output format and channels here
2356 ALOGV("createAudioPatch() setting device %08x on output %d",
François Gaffie53615e22015-03-19 09:24:12 +01002357 devDesc->type(), inputDesc->mIoHandle);
2358 setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002359 index = mAudioPatches.indexOfKey(*handle);
2360 if (index >= 0) {
2361 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2362 ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
2363 }
2364 patchDesc = mAudioPatches.valueAt(index);
2365 patchDesc->mUid = uid;
2366 ALOGV("createAudioPatch() success");
2367 } else {
2368 ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
2369 return INVALID_OPERATION;
2370 }
2371 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2372 // device to device connection
2373 if (patchDesc != 0) {
Eric Laurent874c42872014-08-08 15:13:39 -07002374 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002375 return BAD_VALUE;
2376 }
2377 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002378 sp<DeviceDescriptor> srcDeviceDesc =
2379 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
Eric Laurent58f8eb72014-09-12 16:19:41 -07002380 if (srcDeviceDesc == 0) {
2381 return BAD_VALUE;
2382 }
Eric Laurent874c42872014-08-08 15:13:39 -07002383
Eric Laurent6a94d692014-05-20 11:18:06 -07002384 //update source and sink with our own data as the data passed in the patch may
2385 // be incomplete.
2386 struct audio_patch newPatch = *patch;
2387 srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
Eric Laurent6a94d692014-05-20 11:18:06 -07002388
Eric Laurent874c42872014-08-08 15:13:39 -07002389 for (size_t i = 0; i < patch->num_sinks; i++) {
2390 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2391 ALOGV("createAudioPatch() source device but one sink is not a device");
2392 return INVALID_OPERATION;
2393 }
2394
2395 sp<DeviceDescriptor> sinkDeviceDesc =
2396 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2397 if (sinkDeviceDesc == 0) {
2398 return BAD_VALUE;
2399 }
2400 sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
2401
Eric Laurent3bcf8592015-04-03 12:13:24 -07002402 // create a software bridge in PatchPanel if:
2403 // - source and sink devices are on differnt HW modules OR
2404 // - audio HAL version is < 3.0
2405 if ((srcDeviceDesc->getModuleHandle() != sinkDeviceDesc->getModuleHandle()) ||
2406 (srcDeviceDesc->mModule->mHalVersion < AUDIO_DEVICE_API_VERSION_3_0)) {
2407 // support only one sink device for now to simplify output selection logic
Eric Laurent874c42872014-08-08 15:13:39 -07002408 if (patch->num_sinks > 1) {
Eric Laurent83b88082014-06-20 18:31:16 -07002409 return INVALID_OPERATION;
2410 }
Eric Laurent874c42872014-08-08 15:13:39 -07002411 SortedVector<audio_io_handle_t> outputs =
François Gaffie53615e22015-03-19 09:24:12 +01002412 getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
Eric Laurent874c42872014-08-08 15:13:39 -07002413 // if the sink device is reachable via an opened output stream, request to go via
2414 // this output stream by adding a second source to the patch description
Eric Laurent8838a382014-09-08 16:44:28 -07002415 audio_io_handle_t output = selectOutput(outputs,
2416 AUDIO_OUTPUT_FLAG_NONE,
2417 AUDIO_FORMAT_INVALID);
Eric Laurent874c42872014-08-08 15:13:39 -07002418 if (output != AUDIO_IO_HANDLE_NONE) {
2419 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2420 if (outputDesc->isDuplicated()) {
2421 return INVALID_OPERATION;
2422 }
2423 outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
Eric Laurent3bcf8592015-04-03 12:13:24 -07002424 newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurent874c42872014-08-08 15:13:39 -07002425 newPatch.num_sources = 2;
2426 }
Eric Laurent83b88082014-06-20 18:31:16 -07002427 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002428 }
2429 // TODO: check from routing capabilities in config file and other conflicting patches
2430
2431 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
2432 if (index >= 0) {
2433 afPatchHandle = patchDesc->mAfPatchHandle;
2434 }
2435
2436 status_t status = mpClientInterface->createAudioPatch(&newPatch,
2437 &afPatchHandle,
2438 0);
2439 ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
2440 status, afPatchHandle);
2441 if (status == NO_ERROR) {
2442 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01002443 patchDesc = new AudioPatch(&newPatch, uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07002444 addAudioPatch(patchDesc->mHandle, patchDesc);
2445 } else {
2446 patchDesc->mPatch = newPatch;
2447 }
2448 patchDesc->mAfPatchHandle = afPatchHandle;
2449 *handle = patchDesc->mHandle;
2450 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002451 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002452 } else {
2453 ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
2454 status);
2455 return INVALID_OPERATION;
2456 }
2457 } else {
2458 return BAD_VALUE;
2459 }
2460 } else {
2461 return BAD_VALUE;
2462 }
2463 return NO_ERROR;
2464}
2465
2466status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
2467 uid_t uid)
2468{
2469 ALOGV("releaseAudioPatch() patch %d", handle);
2470
2471 ssize_t index = mAudioPatches.indexOfKey(handle);
2472
2473 if (index < 0) {
2474 return BAD_VALUE;
2475 }
2476 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
2477 ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2478 mUidCached, patchDesc->mUid, uid);
2479 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2480 return INVALID_OPERATION;
2481 }
2482
2483 struct audio_patch *patch = &patchDesc->mPatch;
2484 patchDesc->mUid = mUidCached;
2485 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002486 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002487 if (outputDesc == NULL) {
2488 ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
2489 return BAD_VALUE;
2490 }
2491
Eric Laurentc75307b2015-03-17 15:29:32 -07002492 setOutputDevice(outputDesc,
2493 getNewOutputDevice(outputDesc, true /*fromCache*/),
Eric Laurent6a94d692014-05-20 11:18:06 -07002494 true,
2495 0,
2496 NULL);
2497 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2498 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
François Gaffie53615e22015-03-19 09:24:12 +01002499 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002500 if (inputDesc == NULL) {
2501 ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
2502 return BAD_VALUE;
2503 }
2504 setInputDevice(inputDesc->mIoHandle,
2505 getNewInputDevice(inputDesc->mIoHandle),
2506 true,
2507 NULL);
2508 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2509 audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle;
2510 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
2511 ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
2512 status, patchDesc->mAfPatchHandle);
2513 removeAudioPatch(patchDesc->mHandle);
2514 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002515 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002516 } else {
2517 return BAD_VALUE;
2518 }
2519 } else {
2520 return BAD_VALUE;
2521 }
2522 return NO_ERROR;
2523}
2524
2525status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
2526 struct audio_patch *patches,
2527 unsigned int *generation)
2528{
François Gaffie53615e22015-03-19 09:24:12 +01002529 if (generation == NULL) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002530 return BAD_VALUE;
2531 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002532 *generation = curAudioPortGeneration();
François Gaffie53615e22015-03-19 09:24:12 +01002533 return mAudioPatches.listAudioPatches(num_patches, patches);
Eric Laurent6a94d692014-05-20 11:18:06 -07002534}
2535
Eric Laurente1715a42014-05-20 11:30:42 -07002536status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
Eric Laurent6a94d692014-05-20 11:18:06 -07002537{
Eric Laurente1715a42014-05-20 11:30:42 -07002538 ALOGV("setAudioPortConfig()");
2539
2540 if (config == NULL) {
2541 return BAD_VALUE;
2542 }
2543 ALOGV("setAudioPortConfig() on port handle %d", config->id);
2544 // Only support gain configuration for now
Eric Laurenta121f902014-06-03 13:32:54 -07002545 if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
2546 return INVALID_OPERATION;
Eric Laurente1715a42014-05-20 11:30:42 -07002547 }
2548
Eric Laurenta121f902014-06-03 13:32:54 -07002549 sp<AudioPortConfig> audioPortConfig;
Eric Laurente1715a42014-05-20 11:30:42 -07002550 if (config->type == AUDIO_PORT_TYPE_MIX) {
2551 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002552 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002553 if (outputDesc == NULL) {
2554 return BAD_VALUE;
2555 }
Eric Laurent84c70242014-06-23 08:46:27 -07002556 ALOG_ASSERT(!outputDesc->isDuplicated(),
2557 "setAudioPortConfig() called on duplicated output %d",
2558 outputDesc->mIoHandle);
Eric Laurenta121f902014-06-03 13:32:54 -07002559 audioPortConfig = outputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002560 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
François Gaffie53615e22015-03-19 09:24:12 +01002561 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002562 if (inputDesc == NULL) {
2563 return BAD_VALUE;
2564 }
Eric Laurenta121f902014-06-03 13:32:54 -07002565 audioPortConfig = inputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002566 } else {
2567 return BAD_VALUE;
2568 }
2569 } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
2570 sp<DeviceDescriptor> deviceDesc;
2571 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
2572 deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
2573 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
2574 deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
2575 } else {
2576 return BAD_VALUE;
2577 }
2578 if (deviceDesc == NULL) {
2579 return BAD_VALUE;
2580 }
Eric Laurenta121f902014-06-03 13:32:54 -07002581 audioPortConfig = deviceDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002582 } else {
2583 return BAD_VALUE;
2584 }
2585
Eric Laurenta121f902014-06-03 13:32:54 -07002586 struct audio_port_config backupConfig;
2587 status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
2588 if (status == NO_ERROR) {
2589 struct audio_port_config newConfig;
2590 audioPortConfig->toAudioPortConfig(&newConfig, config);
2591 status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
Eric Laurente1715a42014-05-20 11:30:42 -07002592 }
Eric Laurenta121f902014-06-03 13:32:54 -07002593 if (status != NO_ERROR) {
2594 audioPortConfig->applyAudioPortConfig(&backupConfig);
Eric Laurente1715a42014-05-20 11:30:42 -07002595 }
Eric Laurente1715a42014-05-20 11:30:42 -07002596
2597 return status;
Eric Laurent6a94d692014-05-20 11:18:06 -07002598}
2599
Eric Laurent8c7e6da2015-04-21 17:37:00 -07002600void AudioPolicyManager::releaseResourcesForUid(uid_t uid)
2601{
2602 clearAudioPatches(uid);
2603 clearSessionRoutes(uid);
2604}
2605
Eric Laurent6a94d692014-05-20 11:18:06 -07002606void AudioPolicyManager::clearAudioPatches(uid_t uid)
2607{
Eric Laurent0add0fd2014-12-04 18:58:14 -08002608 for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002609 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
2610 if (patchDesc->mUid == uid) {
Eric Laurent0add0fd2014-12-04 18:58:14 -08002611 releaseAudioPatch(mAudioPatches.keyAt(i), uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07002612 }
2613 }
2614}
2615
Eric Laurent8c7e6da2015-04-21 17:37:00 -07002616
2617void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
2618 audio_io_handle_t ouptutToSkip)
2619{
2620 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
2621 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
2622 for (size_t j = 0; j < mOutputs.size(); j++) {
2623 if (mOutputs.keyAt(j) == ouptutToSkip) {
2624 continue;
2625 }
2626 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
2627 if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
2628 continue;
2629 }
2630 // If the default device for this strategy is on another output mix,
2631 // invalidate all tracks in this strategy to force re connection.
2632 // Otherwise select new device on the output mix.
2633 if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
2634 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
2635 if (stream == AUDIO_STREAM_PATCH) {
2636 continue;
2637 }
2638 if (getStrategy((audio_stream_type_t)stream) == strategy) {
2639 mpClientInterface->invalidateStream((audio_stream_type_t)stream);
2640 }
2641 }
2642 } else {
2643 audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
2644 setOutputDevice(outputDesc, newDevice, false);
2645 }
2646 }
2647}
2648
2649void AudioPolicyManager::clearSessionRoutes(uid_t uid)
2650{
2651 // remove output routes associated with this uid
2652 SortedVector<routing_strategy> affectedStrategies;
2653 for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--) {
2654 sp<SessionRoute> route = mOutputRoutes.valueAt(i);
2655 if (route->mUid == uid) {
2656 mOutputRoutes.removeItemsAt(i);
2657 if (route->mDeviceDescriptor != 0) {
2658 affectedStrategies.add(getStrategy(route->mStreamType));
2659 }
2660 }
2661 }
2662 // reroute outputs if necessary
2663 for (size_t i = 0; i < affectedStrategies.size(); i++) {
2664 checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
2665 }
2666
2667 // remove input routes associated with this uid
2668 SortedVector<audio_source_t> affectedSources;
2669 for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--) {
2670 sp<SessionRoute> route = mInputRoutes.valueAt(i);
2671 if (route->mUid == uid) {
2672 mInputRoutes.removeItemsAt(i);
2673 if (route->mDeviceDescriptor != 0) {
2674 affectedSources.add(route->mSource);
2675 }
2676 }
2677 }
2678 // reroute inputs if necessary
2679 SortedVector<audio_io_handle_t> inputsToClose;
2680 for (size_t i = 0; i < mInputs.size(); i++) {
2681 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
2682 if (affectedSources.indexOf(inputDesc->mInputSource) >= 0) {
2683 inputsToClose.add(inputDesc->mIoHandle);
2684 }
2685 }
2686 for (size_t i = 0; i < inputsToClose.size(); i++) {
2687 closeInput(inputsToClose[i]);
2688 }
2689}
2690
2691
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002692status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
2693 audio_io_handle_t *ioHandle,
2694 audio_devices_t *device)
2695{
2696 *session = (audio_session_t)mpClientInterface->newAudioUniqueId();
2697 *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId();
Eric Laurentc73ca6e2014-12-12 14:34:22 -08002698 *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002699
François Gaffiedf372692015-03-19 10:43:27 +01002700 return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002701}
2702
Eric Laurent493404d2015-04-21 15:07:36 -07002703status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source __unused,
2704 const audio_attributes_t *attributes __unused,
2705 audio_io_handle_t *handle __unused)
Eric Laurent554a2772015-04-10 11:29:24 -07002706{
2707 return INVALID_OPERATION;
2708}
2709
Eric Laurent493404d2015-04-21 15:07:36 -07002710status_t AudioPolicyManager::stopAudioSource(audio_io_handle_t handle __unused)
Eric Laurent554a2772015-04-10 11:29:24 -07002711{
2712 return INVALID_OPERATION;
2713}
2714
Eric Laurente552edb2014-03-10 17:42:56 -07002715// ----------------------------------------------------------------------------
Eric Laurente0720872014-03-11 09:30:41 -07002716// AudioPolicyManager
Eric Laurente552edb2014-03-10 17:42:56 -07002717// ----------------------------------------------------------------------------
Eric Laurent6a94d692014-05-20 11:18:06 -07002718uint32_t AudioPolicyManager::nextAudioPortGeneration()
2719{
2720 return android_atomic_inc(&mAudioPortGeneration);
2721}
2722
Eric Laurente0720872014-03-11 09:30:41 -07002723AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
Eric Laurente552edb2014-03-10 17:42:56 -07002724 :
2725#ifdef AUDIO_POLICY_TEST
2726 Thread(false),
2727#endif //AUDIO_POLICY_TEST
Eric Laurente552edb2014-03-10 17:42:56 -07002728 mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
Eric Laurent3a4311c2014-03-17 12:00:47 -07002729 mA2dpSuspended(false),
Paul McLeane743a472015-01-28 11:07:31 -08002730 mSpeakerDrcEnabled(false),
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07002731 mAudioPortGeneration(1),
2732 mBeaconMuteRefCount(0),
2733 mBeaconPlayingRefCount(0),
Eric Laurent9459fb02015-08-12 18:36:32 -07002734 mBeaconMuted(false),
2735 mTtsOutputAvailable(false)
Eric Laurente552edb2014-03-10 17:42:56 -07002736{
François Gaffie2110e042015-03-24 08:41:51 +01002737 audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
2738 if (!engineInstance) {
2739 ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
2740 return;
2741 }
2742 // Retrieve the Policy Manager Interface
2743 mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
2744 if (mEngine == NULL) {
2745 ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
2746 return;
2747 }
2748 mEngine->setObserver(this);
2749 status_t status = mEngine->initCheck();
2750 ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
2751
Eric Laurent6a94d692014-05-20 11:18:06 -07002752 mUidCached = getuid();
Eric Laurente552edb2014-03-10 17:42:56 -07002753 mpClientInterface = clientInterface;
2754
Eric Laurent7288ab82015-05-06 18:44:02 -07002755 mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER);
François Gaffie53615e22015-03-19 09:24:12 +01002756 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE,
2757 mHwModules, mAvailableInputDevices, mAvailableOutputDevices,
2758 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {
2759 if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE,
2760 mHwModules, mAvailableInputDevices, mAvailableOutputDevices,
2761 mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) {
Eric Laurente552edb2014-03-10 17:42:56 -07002762 ALOGE("could not load audio policy configuration file, setting defaults");
2763 defaultAudioPolicyConfig();
2764 }
2765 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002766 // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
Eric Laurente552edb2014-03-10 17:42:56 -07002767
François Gaffie2110e042015-03-24 08:41:51 +01002768 // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
2769 mEngine->initializeVolumeCurves(mSpeakerDrcEnabled);
Eric Laurente552edb2014-03-10 17:42:56 -07002770
2771 // open all output streams needed to access attached devices
Eric Laurent3a4311c2014-03-17 12:00:47 -07002772 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
2773 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
Eric Laurente552edb2014-03-10 17:42:56 -07002774 for (size_t i = 0; i < mHwModules.size(); i++) {
2775 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
2776 if (mHwModules[i]->mHandle == 0) {
2777 ALOGW("could not open HW module %s", mHwModules[i]->mName);
2778 continue;
2779 }
2780 // open all output streams needed to access attached devices
2781 // except for direct output streams that are only opened when they are actually
2782 // required by an app.
Eric Laurent3a4311c2014-03-17 12:00:47 -07002783 // This also validates mAvailableOutputDevices list
Eric Laurente552edb2014-03-10 17:42:56 -07002784 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2785 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002786 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002787
Eric Laurent3a4311c2014-03-17 12:00:47 -07002788 if (outProfile->mSupportedDevices.isEmpty()) {
2789 ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
2790 continue;
2791 }
Eric Laurent9459fb02015-08-12 18:36:32 -07002792 if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_TTS) != 0) {
2793 mTtsOutputAvailable = true;
2794 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002795
Eric Laurentd78f1532014-09-16 16:38:20 -07002796 if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
2797 continue;
2798 }
Eric Laurent83b88082014-06-20 18:31:16 -07002799 audio_devices_t profileType = outProfile->mSupportedDevices.types();
François Gaffie53615e22015-03-19 09:24:12 +01002800 if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
2801 profileType = mDefaultOutputDevice->type();
Eric Laurent83b88082014-06-20 18:31:16 -07002802 } else {
Eric Laurentd78f1532014-09-16 16:38:20 -07002803 // chose first device present in mSupportedDevices also part of
2804 // outputDeviceTypes
2805 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002806 profileType = outProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002807 if ((profileType & outputDeviceTypes) != 0) {
2808 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002809 }
Eric Laurente552edb2014-03-10 17:42:56 -07002810 }
2811 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002812 if ((profileType & outputDeviceTypes) == 0) {
2813 continue;
2814 }
Eric Laurentc75307b2015-03-17 15:29:32 -07002815 sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
2816 mpClientInterface);
Eric Laurentd78f1532014-09-16 16:38:20 -07002817
2818 outputDesc->mDevice = profileType;
2819 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2820 config.sample_rate = outputDesc->mSamplingRate;
2821 config.channel_mask = outputDesc->mChannelMask;
2822 config.format = outputDesc->mFormat;
2823 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07002824 status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
Eric Laurentd78f1532014-09-16 16:38:20 -07002825 &output,
2826 &config,
2827 &outputDesc->mDevice,
2828 String8(""),
2829 &outputDesc->mLatency,
2830 outputDesc->mFlags);
2831
2832 if (status != NO_ERROR) {
2833 ALOGW("Cannot open output stream for device %08x on hw module %s",
2834 outputDesc->mDevice,
2835 mHwModules[i]->mName);
2836 } else {
2837 outputDesc->mSamplingRate = config.sample_rate;
2838 outputDesc->mChannelMask = config.channel_mask;
2839 outputDesc->mFormat = config.format;
2840
2841 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002842 audio_devices_t type = outProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002843 ssize_t index =
2844 mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
2845 // give a valid ID to an attached device once confirmed it is reachable
Paul McLeane743a472015-01-28 11:07:31 -08002846 if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
2847 mAvailableOutputDevices[index]->attach(mHwModules[i]);
Eric Laurentd78f1532014-09-16 16:38:20 -07002848 }
2849 }
2850 if (mPrimaryOutput == 0 &&
2851 outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002852 mPrimaryOutput = outputDesc;
Eric Laurentd78f1532014-09-16 16:38:20 -07002853 }
2854 addOutput(output, outputDesc);
Eric Laurentc75307b2015-03-17 15:29:32 -07002855 setOutputDevice(outputDesc,
Eric Laurentd78f1532014-09-16 16:38:20 -07002856 outputDesc->mDevice,
2857 true);
2858 }
Eric Laurente552edb2014-03-10 17:42:56 -07002859 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002860 // open input streams needed to access attached devices to validate
2861 // mAvailableInputDevices list
2862 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
2863 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002864 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002865
Eric Laurent3a4311c2014-03-17 12:00:47 -07002866 if (inProfile->mSupportedDevices.isEmpty()) {
2867 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
2868 continue;
2869 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002870 // chose first device present in mSupportedDevices also part of
2871 // inputDeviceTypes
2872 audio_devices_t profileType = AUDIO_DEVICE_NONE;
2873 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002874 profileType = inProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002875 if (profileType & inputDeviceTypes) {
2876 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002877 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002878 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002879 if ((profileType & inputDeviceTypes) == 0) {
2880 continue;
2881 }
2882 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);
2883
2884 inputDesc->mInputSource = AUDIO_SOURCE_MIC;
2885 inputDesc->mDevice = profileType;
2886
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07002887 // find the address
2888 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
2889 // the inputs vector must be of size 1, but we don't want to crash here
2890 String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
2891 : String8("");
2892 ALOGV(" for input device 0x%x using address %s", profileType, address.string());
2893 ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
2894
Eric Laurentd78f1532014-09-16 16:38:20 -07002895 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2896 config.sample_rate = inputDesc->mSamplingRate;
2897 config.channel_mask = inputDesc->mChannelMask;
2898 config.format = inputDesc->mFormat;
2899 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07002900 status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
Eric Laurentd78f1532014-09-16 16:38:20 -07002901 &input,
2902 &config,
2903 &inputDesc->mDevice,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07002904 address,
Eric Laurentd78f1532014-09-16 16:38:20 -07002905 AUDIO_SOURCE_MIC,
2906 AUDIO_INPUT_FLAG_NONE);
2907
2908 if (status == NO_ERROR) {
2909 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
François Gaffie53615e22015-03-19 09:24:12 +01002910 audio_devices_t type = inProfile->mSupportedDevices[k]->type();
Eric Laurentd78f1532014-09-16 16:38:20 -07002911 ssize_t index =
2912 mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
2913 // give a valid ID to an attached device once confirmed it is reachable
Eric Laurent45aabc32015-08-06 09:11:13 -07002914 if (index >= 0) {
2915 sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
2916 if (!devDesc->isAttached()) {
2917 devDesc->attach(mHwModules[i]);
2918 devDesc->importAudioPort(inProfile);
2919 }
Eric Laurentd78f1532014-09-16 16:38:20 -07002920 }
2921 }
2922 mpClientInterface->closeInput(input);
2923 } else {
2924 ALOGW("Cannot open input stream for device %08x on hw module %s",
2925 inputDesc->mDevice,
2926 mHwModules[i]->mName);
2927 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002928 }
2929 }
2930 // make sure all attached devices have been allocated a unique ID
2931 for (size_t i = 0; i < mAvailableOutputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08002932 if (!mAvailableOutputDevices[i]->isAttached()) {
François Gaffie53615e22015-03-19 09:24:12 +01002933 ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002934 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
2935 continue;
2936 }
François Gaffie2110e042015-03-24 08:41:51 +01002937 // The device is now validated and can be appended to the available devices of the engine
2938 mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
2939 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002940 i++;
2941 }
2942 for (size_t i = 0; i < mAvailableInputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08002943 if (!mAvailableInputDevices[i]->isAttached()) {
François Gaffie53615e22015-03-19 09:24:12 +01002944 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002945 mAvailableInputDevices.remove(mAvailableInputDevices[i]);
2946 continue;
2947 }
François Gaffie2110e042015-03-24 08:41:51 +01002948 // The device is now validated and can be appended to the available devices of the engine
2949 mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
2950 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002951 i++;
2952 }
2953 // make sure default device is reachable
2954 if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
François Gaffie53615e22015-03-19 09:24:12 +01002955 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07002956 }
Eric Laurente552edb2014-03-10 17:42:56 -07002957
2958 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
2959
2960 updateDevicesAndOutputs();
2961
2962#ifdef AUDIO_POLICY_TEST
2963 if (mPrimaryOutput != 0) {
2964 AudioParameter outputCmd = AudioParameter();
2965 outputCmd.addInt(String8("set_id"), 0);
Eric Laurentc75307b2015-03-17 15:29:32 -07002966 mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());
Eric Laurente552edb2014-03-10 17:42:56 -07002967
2968 mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
2969 mTestSamplingRate = 44100;
Eric Laurent3b73df72014-03-11 09:06:29 -07002970 mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
2971 mTestChannels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07002972 mTestLatencyMs = 0;
2973 mCurOutput = 0;
2974 mDirectOutput = false;
2975 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
2976 mTestOutputs[i] = 0;
2977 }
2978
2979 const size_t SIZE = 256;
2980 char buffer[SIZE];
2981 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
2982 run(buffer, ANDROID_PRIORITY_AUDIO);
2983 }
2984#endif //AUDIO_POLICY_TEST
2985}
2986
Eric Laurente0720872014-03-11 09:30:41 -07002987AudioPolicyManager::~AudioPolicyManager()
Eric Laurente552edb2014-03-10 17:42:56 -07002988{
2989#ifdef AUDIO_POLICY_TEST
2990 exit();
2991#endif //AUDIO_POLICY_TEST
2992 for (size_t i = 0; i < mOutputs.size(); i++) {
2993 mpClientInterface->closeOutput(mOutputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002994 }
2995 for (size_t i = 0; i < mInputs.size(); i++) {
2996 mpClientInterface->closeInput(mInputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002997 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002998 mAvailableOutputDevices.clear();
2999 mAvailableInputDevices.clear();
Eric Laurent1f2f2232014-06-02 12:01:23 -07003000 mOutputs.clear();
3001 mInputs.clear();
3002 mHwModules.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07003003}
3004
Eric Laurente0720872014-03-11 09:30:41 -07003005status_t AudioPolicyManager::initCheck()
Eric Laurente552edb2014-03-10 17:42:56 -07003006{
Eric Laurent87ffa392015-05-22 10:32:38 -07003007 return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003008}
3009
3010#ifdef AUDIO_POLICY_TEST
Eric Laurente0720872014-03-11 09:30:41 -07003011bool AudioPolicyManager::threadLoop()
Eric Laurente552edb2014-03-10 17:42:56 -07003012{
3013 ALOGV("entering threadLoop()");
3014 while (!exitPending())
3015 {
3016 String8 command;
3017 int valueInt;
3018 String8 value;
3019
3020 Mutex::Autolock _l(mLock);
3021 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
3022
3023 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
3024 AudioParameter param = AudioParameter(command);
3025
3026 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
3027 valueInt != 0) {
3028 ALOGV("Test command %s received", command.string());
3029 String8 target;
3030 if (param.get(String8("target"), target) != NO_ERROR) {
3031 target = "Manager";
3032 }
3033 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
3034 param.remove(String8("test_cmd_policy_output"));
3035 mCurOutput = valueInt;
3036 }
3037 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
3038 param.remove(String8("test_cmd_policy_direct"));
3039 if (value == "false") {
3040 mDirectOutput = false;
3041 } else if (value == "true") {
3042 mDirectOutput = true;
3043 }
3044 }
3045 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
3046 param.remove(String8("test_cmd_policy_input"));
3047 mTestInput = valueInt;
3048 }
3049
3050 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
3051 param.remove(String8("test_cmd_policy_format"));
Eric Laurent3b73df72014-03-11 09:06:29 -07003052 int format = AUDIO_FORMAT_INVALID;
Eric Laurente552edb2014-03-10 17:42:56 -07003053 if (value == "PCM 16 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003054 format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003055 } else if (value == "PCM 8 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003056 format = AUDIO_FORMAT_PCM_8_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003057 } else if (value == "Compressed MP3") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003058 format = AUDIO_FORMAT_MP3;
Eric Laurente552edb2014-03-10 17:42:56 -07003059 }
Eric Laurent3b73df72014-03-11 09:06:29 -07003060 if (format != AUDIO_FORMAT_INVALID) {
Eric Laurente552edb2014-03-10 17:42:56 -07003061 if (target == "Manager") {
3062 mTestFormat = format;
3063 } else if (mTestOutputs[mCurOutput] != 0) {
3064 AudioParameter outputParam = AudioParameter();
3065 outputParam.addInt(String8("format"), format);
3066 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3067 }
3068 }
3069 }
3070 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
3071 param.remove(String8("test_cmd_policy_channels"));
3072 int channels = 0;
3073
3074 if (value == "Channels Stereo") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003075 channels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07003076 } else if (value == "Channels Mono") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003077 channels = AUDIO_CHANNEL_OUT_MONO;
Eric Laurente552edb2014-03-10 17:42:56 -07003078 }
3079 if (channels != 0) {
3080 if (target == "Manager") {
3081 mTestChannels = channels;
3082 } else if (mTestOutputs[mCurOutput] != 0) {
3083 AudioParameter outputParam = AudioParameter();
3084 outputParam.addInt(String8("channels"), channels);
3085 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3086 }
3087 }
3088 }
3089 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
3090 param.remove(String8("test_cmd_policy_sampleRate"));
3091 if (valueInt >= 0 && valueInt <= 96000) {
3092 int samplingRate = valueInt;
3093 if (target == "Manager") {
3094 mTestSamplingRate = samplingRate;
3095 } else if (mTestOutputs[mCurOutput] != 0) {
3096 AudioParameter outputParam = AudioParameter();
3097 outputParam.addInt(String8("sampling_rate"), samplingRate);
3098 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3099 }
3100 }
3101 }
3102
3103 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
3104 param.remove(String8("test_cmd_policy_reopen"));
3105
Eric Laurentc75307b2015-03-17 15:29:32 -07003106 mpClientInterface->closeOutput(mpClientInterface->closeOutput(mPrimaryOutput););
Eric Laurente552edb2014-03-10 17:42:56 -07003107
Eric Laurentc75307b2015-03-17 15:29:32 -07003108 audio_module_handle_t moduleHandle = mPrimaryOutput->getModuleHandle();
Eric Laurente552edb2014-03-10 17:42:56 -07003109
Eric Laurentc75307b2015-03-17 15:29:32 -07003110 removeOutput(mPrimaryOutput->mIoHandle);
3111 sp<SwAudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL,
3112 mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -07003113 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003114 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3115 config.sample_rate = outputDesc->mSamplingRate;
3116 config.channel_mask = outputDesc->mChannelMask;
3117 config.format = outputDesc->mFormat;
Eric Laurentc75307b2015-03-17 15:29:32 -07003118 audio_io_handle_t handle;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003119 status_t status = mpClientInterface->openOutput(moduleHandle,
Eric Laurentc75307b2015-03-17 15:29:32 -07003120 &handle,
Eric Laurentcf2c0212014-07-25 16:20:43 -07003121 &config,
3122 &outputDesc->mDevice,
3123 String8(""),
3124 &outputDesc->mLatency,
3125 outputDesc->mFlags);
3126 if (status != NO_ERROR) {
3127 ALOGE("Failed to reopen hardware output stream, "
3128 "samplingRate: %d, format %d, channels %d",
3129 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
Eric Laurente552edb2014-03-10 17:42:56 -07003130 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003131 outputDesc->mSamplingRate = config.sample_rate;
3132 outputDesc->mChannelMask = config.channel_mask;
3133 outputDesc->mFormat = config.format;
Eric Laurentc75307b2015-03-17 15:29:32 -07003134 mPrimaryOutput = outputDesc;
Eric Laurente552edb2014-03-10 17:42:56 -07003135 AudioParameter outputCmd = AudioParameter();
3136 outputCmd.addInt(String8("set_id"), 0);
Eric Laurentc75307b2015-03-17 15:29:32 -07003137 mpClientInterface->setParameters(handle, outputCmd.toString());
3138 addOutput(handle, outputDesc);
Eric Laurente552edb2014-03-10 17:42:56 -07003139 }
3140 }
3141
3142
3143 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
3144 }
3145 }
3146 return false;
3147}
3148
Eric Laurente0720872014-03-11 09:30:41 -07003149void AudioPolicyManager::exit()
Eric Laurente552edb2014-03-10 17:42:56 -07003150{
3151 {
3152 AutoMutex _l(mLock);
3153 requestExit();
3154 mWaitWorkCV.signal();
3155 }
3156 requestExitAndWait();
3157}
3158
Eric Laurente0720872014-03-11 09:30:41 -07003159int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07003160{
3161 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3162 if (output == mTestOutputs[i]) return i;
3163 }
3164 return 0;
3165}
3166#endif //AUDIO_POLICY_TEST
3167
3168// ---
3169
Eric Laurentc75307b2015-03-17 15:29:32 -07003170void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<SwAudioOutputDescriptor> outputDesc)
Eric Laurente552edb2014-03-10 17:42:56 -07003171{
François Gaffie98cc1912015-03-18 17:52:40 +01003172 outputDesc->setIoHandle(output);
Eric Laurent1c333e22014-05-20 10:48:17 -07003173 mOutputs.add(output, outputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07003174 nextAudioPortGeneration();
Eric Laurente552edb2014-03-10 17:42:56 -07003175}
3176
François Gaffie53615e22015-03-19 09:24:12 +01003177void AudioPolicyManager::removeOutput(audio_io_handle_t output)
3178{
3179 mOutputs.removeItem(output);
3180}
3181
Eric Laurent1f2f2232014-06-02 12:01:23 -07003182void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc)
Eric Laurentd4692962014-05-05 18:13:44 -07003183{
François Gaffie98cc1912015-03-18 17:52:40 +01003184 inputDesc->setIoHandle(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07003185 mInputs.add(input, inputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07003186 nextAudioPortGeneration();
Eric Laurentd4692962014-05-05 18:13:44 -07003187}
Eric Laurente552edb2014-03-10 17:42:56 -07003188
Eric Laurentc75307b2015-03-17 15:29:32 -07003189void AudioPolicyManager::findIoHandlesByAddress(sp<SwAudioOutputDescriptor> desc /*in*/,
keunyoung3190e672014-12-30 13:00:52 -08003190 const audio_devices_t device /*in*/,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003191 const String8 address /*in*/,
3192 SortedVector<audio_io_handle_t>& outputs /*out*/) {
keunyoung3190e672014-12-30 13:00:52 -08003193 sp<DeviceDescriptor> devDesc =
3194 desc->mProfile->mSupportedDevices.getDevice(device, address);
3195 if (devDesc != 0) {
3196 ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
3197 desc->mIoHandle, address.string());
3198 outputs.add(desc->mIoHandle);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003199 }
3200}
3201
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003202status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
François Gaffie53615e22015-03-19 09:24:12 +01003203 audio_policy_dev_state_t state,
3204 SortedVector<audio_io_handle_t>& outputs,
3205 const String8 address)
Eric Laurente552edb2014-03-10 17:42:56 -07003206{
François Gaffie53615e22015-03-19 09:24:12 +01003207 audio_devices_t device = devDesc->type();
Eric Laurentc75307b2015-03-17 15:29:32 -07003208 sp<SwAudioOutputDescriptor> desc;
Eric Laurentcc750d32015-06-25 11:48:20 -07003209
3210 if (audio_device_is_digital(device)) {
3211 // erase all current sample rates, formats and channel masks
3212 devDesc->clearCapabilities();
3213 }
Eric Laurente552edb2014-03-10 17:42:56 -07003214
Eric Laurent3b73df72014-03-11 09:06:29 -07003215 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003216 // first list already open outputs that can be routed to this device
3217 for (size_t i = 0; i < mOutputs.size(); i++) {
3218 desc = mOutputs.valueAt(i);
Eric Laurentc75307b2015-03-17 15:29:32 -07003219 if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
François Gaffie53615e22015-03-19 09:24:12 +01003220 if (!device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003221 ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
3222 outputs.add(mOutputs.keyAt(i));
3223 } else {
3224 ALOGV(" checking address match due to device 0x%x", device);
keunyoung3190e672014-12-30 13:00:52 -08003225 findIoHandlesByAddress(desc, device, address, outputs);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003226 }
Eric Laurente552edb2014-03-10 17:42:56 -07003227 }
3228 }
3229 // then look for output profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07003230 SortedVector< sp<IOProfile> > profiles;
Eric Laurente552edb2014-03-10 17:42:56 -07003231 for (size_t i = 0; i < mHwModules.size(); i++)
3232 {
3233 if (mHwModules[i]->mHandle == 0) {
3234 continue;
3235 }
3236 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3237 {
Eric Laurent275e8e92014-11-30 15:14:47 -08003238 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
3239 if (profile->mSupportedDevices.types() & device) {
François Gaffie53615e22015-03-19 09:24:12 +01003240 if (!device_distinguishes_on_address(device) ||
Eric Laurent275e8e92014-11-30 15:14:47 -08003241 address == profile->mSupportedDevices[0]->mAddress) {
3242 profiles.add(profile);
3243 ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
3244 }
Eric Laurente552edb2014-03-10 17:42:56 -07003245 }
3246 }
3247 }
3248
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003249 ALOGV(" found %d profiles, %d outputs", profiles.size(), outputs.size());
3250
Eric Laurente552edb2014-03-10 17:42:56 -07003251 if (profiles.isEmpty() && outputs.isEmpty()) {
3252 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3253 return BAD_VALUE;
3254 }
3255
3256 // open outputs for matching profiles if needed. Direct outputs are also opened to
3257 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3258 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003259 sp<IOProfile> profile = profiles[profile_index];
Eric Laurente552edb2014-03-10 17:42:56 -07003260
3261 // nothing to do if one output is already opened for this profile
3262 size_t j;
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003263 for (j = 0; j < outputs.size(); j++) {
3264 desc = mOutputs.valueFor(outputs.itemAt(j));
Eric Laurente552edb2014-03-10 17:42:56 -07003265 if (!desc->isDuplicated() && desc->mProfile == profile) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003266 // matching profile: save the sample rates, format and channel masks supported
3267 // by the profile in our device descriptor
Paul McLean9080a4c2015-06-18 08:24:02 -07003268 if (audio_device_is_digital(device)) {
3269 devDesc->importAudioPort(profile);
3270 }
Eric Laurente552edb2014-03-10 17:42:56 -07003271 break;
3272 }
3273 }
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003274 if (j != outputs.size()) {
Eric Laurente552edb2014-03-10 17:42:56 -07003275 continue;
3276 }
3277
Eric Laurent83b88082014-06-20 18:31:16 -07003278 ALOGV("opening output for device %08x with params %s profile %p",
3279 device, address.string(), profile.get());
Eric Laurentc75307b2015-03-17 15:29:32 -07003280 desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -07003281 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003282 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3283 config.sample_rate = desc->mSamplingRate;
3284 config.channel_mask = desc->mChannelMask;
3285 config.format = desc->mFormat;
3286 config.offload_info.sample_rate = desc->mSamplingRate;
3287 config.offload_info.channel_mask = desc->mChannelMask;
3288 config.offload_info.format = desc->mFormat;
3289 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07003290 status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07003291 &output,
3292 &config,
3293 &desc->mDevice,
3294 address,
3295 &desc->mLatency,
3296 desc->mFlags);
3297 if (status == NO_ERROR) {
3298 desc->mSamplingRate = config.sample_rate;
3299 desc->mChannelMask = config.channel_mask;
3300 desc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07003301
Eric Laurentd4692962014-05-05 18:13:44 -07003302 // Here is where the out_set_parameters() for card & device gets called
Eric Laurent3a4311c2014-03-17 12:00:47 -07003303 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003304 char *param = audio_device_address_to_parameter(device, address);
3305 mpClientInterface->setParameters(output, String8(param));
3306 free(param);
Eric Laurente552edb2014-03-10 17:42:56 -07003307 }
3308
Eric Laurentd4692962014-05-05 18:13:44 -07003309 // Here is where we step through and resolve any "dynamic" fields
3310 String8 reply;
3311 char *value;
3312 if (profile->mSamplingRates[0] == 0) {
3313 reply = mpClientInterface->getParameters(output,
3314 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003315 ALOGV("checkOutputsForDevice() supported sampling rates %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003316 reply.string());
3317 value = strpbrk((char *)reply.string(), "=");
3318 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003319 profile->loadSamplingRates(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003320 }
Eric Laurentd4692962014-05-05 18:13:44 -07003321 }
3322 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3323 reply = mpClientInterface->getParameters(output,
3324 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003325 ALOGV("checkOutputsForDevice() supported formats %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003326 reply.string());
3327 value = strpbrk((char *)reply.string(), "=");
3328 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003329 profile->loadFormats(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003330 }
Eric Laurentd4692962014-05-05 18:13:44 -07003331 }
3332 if (profile->mChannelMasks[0] == 0) {
3333 reply = mpClientInterface->getParameters(output,
3334 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003335 ALOGV("checkOutputsForDevice() supported channel masks %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003336 reply.string());
3337 value = strpbrk((char *)reply.string(), "=");
3338 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003339 profile->loadOutChannels(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003340 }
Eric Laurentd4692962014-05-05 18:13:44 -07003341 }
3342 if (((profile->mSamplingRates[0] == 0) &&
3343 (profile->mSamplingRates.size() < 2)) ||
3344 ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
3345 (profile->mFormats.size() < 2)) ||
3346 ((profile->mChannelMasks[0] == 0) &&
3347 (profile->mChannelMasks.size() < 2))) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003348 ALOGW("checkOutputsForDevice() missing param");
Eric Laurentd4692962014-05-05 18:13:44 -07003349 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003350 output = AUDIO_IO_HANDLE_NONE;
Eric Laurent1e693b52014-07-09 15:03:28 -07003351 } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 ||
3352 profile->mChannelMasks[0] == 0) {
Eric Laurentd4692962014-05-05 18:13:44 -07003353 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003354 config.sample_rate = profile->pickSamplingRate();
3355 config.channel_mask = profile->pickChannelMask();
3356 config.format = profile->pickFormat();
3357 config.offload_info.sample_rate = config.sample_rate;
3358 config.offload_info.channel_mask = config.channel_mask;
3359 config.offload_info.format = config.format;
Eric Laurent322b4d22015-04-03 15:57:54 -07003360 status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07003361 &output,
3362 &config,
3363 &desc->mDevice,
3364 address,
3365 &desc->mLatency,
3366 desc->mFlags);
3367 if (status == NO_ERROR) {
3368 desc->mSamplingRate = config.sample_rate;
3369 desc->mChannelMask = config.channel_mask;
3370 desc->mFormat = config.format;
3371 } else {
3372 output = AUDIO_IO_HANDLE_NONE;
3373 }
Eric Laurentd4692962014-05-05 18:13:44 -07003374 }
3375
Eric Laurentcf2c0212014-07-25 16:20:43 -07003376 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003377 addOutput(output, desc);
François Gaffie53615e22015-03-19 09:24:12 +01003378 if (device_distinguishes_on_address(device) && address != "0") {
François Gaffie036e1e92015-03-19 10:16:24 +01003379 sp<AudioPolicyMix> policyMix;
3380 if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08003381 ALOGE("checkOutputsForDevice() cannot find policy for address %s",
3382 address.string());
3383 }
François Gaffie036e1e92015-03-19 10:16:24 +01003384 policyMix->setOutput(desc);
Jean-Michel Trividacc06f2015-04-08 18:16:39 -07003385 desc->mPolicyMix = policyMix->getMix();
François Gaffie036e1e92015-03-19 10:16:24 +01003386
Eric Laurent87ffa392015-05-22 10:32:38 -07003387 } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
3388 hasPrimaryOutput()) {
Eric Laurentc722f302014-12-10 11:21:49 -08003389 // no duplicated output for direct outputs and
3390 // outputs used by dynamic policy mixes
Eric Laurentcf2c0212014-07-25 16:20:43 -07003391 audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003392
Eric Laurentd4692962014-05-05 18:13:44 -07003393 // set initial stream volume for device
Eric Laurentc75307b2015-03-17 15:29:32 -07003394 applyStreamVolumes(desc, device, 0, true);
Eric Laurente552edb2014-03-10 17:42:56 -07003395
Eric Laurentd4692962014-05-05 18:13:44 -07003396 //TODO: configure audio effect output stage here
3397
3398 // open a duplicating output thread for the new output and the primary output
Eric Laurentc75307b2015-03-17 15:29:32 -07003399 duplicatedOutput =
3400 mpClientInterface->openDuplicateOutput(output,
3401 mPrimaryOutput->mIoHandle);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003402 if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003403 // add duplicated output descriptor
Eric Laurentc75307b2015-03-17 15:29:32 -07003404 sp<SwAudioOutputDescriptor> dupOutputDesc =
3405 new SwAudioOutputDescriptor(NULL, mpClientInterface);
3406 dupOutputDesc->mOutput1 = mPrimaryOutput;
3407 dupOutputDesc->mOutput2 = desc;
Eric Laurentd4692962014-05-05 18:13:44 -07003408 dupOutputDesc->mSamplingRate = desc->mSamplingRate;
3409 dupOutputDesc->mFormat = desc->mFormat;
3410 dupOutputDesc->mChannelMask = desc->mChannelMask;
3411 dupOutputDesc->mLatency = desc->mLatency;
3412 addOutput(duplicatedOutput, dupOutputDesc);
Eric Laurentc75307b2015-03-17 15:29:32 -07003413 applyStreamVolumes(dupOutputDesc, device, 0, true);
Eric Laurentd4692962014-05-05 18:13:44 -07003414 } else {
3415 ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
Eric Laurentc75307b2015-03-17 15:29:32 -07003416 mPrimaryOutput->mIoHandle, output);
Eric Laurentd4692962014-05-05 18:13:44 -07003417 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01003418 removeOutput(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07003419 nextAudioPortGeneration();
Eric Laurentcf2c0212014-07-25 16:20:43 -07003420 output = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003421 }
Eric Laurente552edb2014-03-10 17:42:56 -07003422 }
3423 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003424 } else {
3425 output = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003426 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003427 if (output == AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003428 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07003429 profiles.removeAt(profile_index);
3430 profile_index--;
3431 } else {
3432 outputs.add(output);
Paul McLean9080a4c2015-06-18 08:24:02 -07003433 // Load digital format info only for digital devices
3434 if (audio_device_is_digital(device)) {
3435 devDesc->importAudioPort(profile);
3436 }
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003437
François Gaffie53615e22015-03-19 09:24:12 +01003438 if (device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003439 ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
3440 device, address.string());
Eric Laurentc75307b2015-03-17 15:29:32 -07003441 setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003442 NULL/*patch handle*/, address.string());
3443 }
Eric Laurente552edb2014-03-10 17:42:56 -07003444 ALOGV("checkOutputsForDevice(): adding output %d", output);
3445 }
3446 }
3447
3448 if (profiles.isEmpty()) {
3449 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3450 return BAD_VALUE;
3451 }
Eric Laurentd4692962014-05-05 18:13:44 -07003452 } else { // Disconnect
Eric Laurente552edb2014-03-10 17:42:56 -07003453 // check if one opened output is not needed any more after disconnecting one device
3454 for (size_t i = 0; i < mOutputs.size(); i++) {
3455 desc = mOutputs.valueAt(i);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003456 if (!desc->isDuplicated()) {
Eric Laurent275e8e92014-11-30 15:14:47 -08003457 // exact match on device
François Gaffie53615e22015-03-19 09:24:12 +01003458 if (device_distinguishes_on_address(device) &&
Eric Laurentc75307b2015-03-17 15:29:32 -07003459 (desc->supportedDevices() == device)) {
keunyoung3190e672014-12-30 13:00:52 -08003460 findIoHandlesByAddress(desc, device, address, outputs);
Eric Laurentc75307b2015-03-17 15:29:32 -07003461 } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003462 ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
3463 mOutputs.keyAt(i));
3464 outputs.add(mOutputs.keyAt(i));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003465 }
Eric Laurente552edb2014-03-10 17:42:56 -07003466 }
3467 }
Eric Laurentd4692962014-05-05 18:13:44 -07003468 // Clear any profiles associated with the disconnected device.
Eric Laurente552edb2014-03-10 17:42:56 -07003469 for (size_t i = 0; i < mHwModules.size(); i++)
3470 {
3471 if (mHwModules[i]->mHandle == 0) {
3472 continue;
3473 }
3474 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3475 {
Eric Laurent1c333e22014-05-20 10:48:17 -07003476 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07003477 if (profile->mSupportedDevices.types() & device) {
3478 ALOGV("checkOutputsForDevice(): "
3479 "clearing direct output profile %zu on module %zu", j, i);
Eric Laurente552edb2014-03-10 17:42:56 -07003480 if (profile->mSamplingRates[0] == 0) {
3481 profile->mSamplingRates.clear();
3482 profile->mSamplingRates.add(0);
3483 }
3484 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3485 profile->mFormats.clear();
3486 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3487 }
3488 if (profile->mChannelMasks[0] == 0) {
3489 profile->mChannelMasks.clear();
3490 profile->mChannelMasks.add(0);
3491 }
3492 }
3493 }
3494 }
3495 }
3496 return NO_ERROR;
3497}
3498
Paul McLean9080a4c2015-06-18 08:24:02 -07003499status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor> devDesc,
François Gaffie53615e22015-03-19 09:24:12 +01003500 audio_policy_dev_state_t state,
3501 SortedVector<audio_io_handle_t>& inputs,
3502 const String8 address)
Eric Laurentd4692962014-05-05 18:13:44 -07003503{
Paul McLean9080a4c2015-06-18 08:24:02 -07003504 audio_devices_t device = devDesc->type();
Eric Laurent1f2f2232014-06-02 12:01:23 -07003505 sp<AudioInputDescriptor> desc;
Eric Laurentcc750d32015-06-25 11:48:20 -07003506
3507 if (audio_device_is_digital(device)) {
3508 // erase all current sample rates, formats and channel masks
3509 devDesc->clearCapabilities();
3510 }
3511
Eric Laurentd4692962014-05-05 18:13:44 -07003512 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3513 // first list already open inputs that can be routed to this device
3514 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3515 desc = mInputs.valueAt(input_index);
3516 if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
3517 ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
3518 inputs.add(mInputs.keyAt(input_index));
3519 }
3520 }
3521
3522 // then look for input profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07003523 SortedVector< sp<IOProfile> > profiles;
Eric Laurentd4692962014-05-05 18:13:44 -07003524 for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
3525 {
3526 if (mHwModules[module_idx]->mHandle == 0) {
3527 continue;
3528 }
3529 for (size_t profile_index = 0;
3530 profile_index < mHwModules[module_idx]->mInputProfiles.size();
3531 profile_index++)
3532 {
Eric Laurent275e8e92014-11-30 15:14:47 -08003533 sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
3534
3535 if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
François Gaffie53615e22015-03-19 09:24:12 +01003536 if (!device_distinguishes_on_address(device) ||
Eric Laurent275e8e92014-11-30 15:14:47 -08003537 address == profile->mSupportedDevices[0]->mAddress) {
3538 profiles.add(profile);
3539 ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
3540 profile_index, module_idx);
3541 }
Eric Laurentd4692962014-05-05 18:13:44 -07003542 }
3543 }
3544 }
3545
3546 if (profiles.isEmpty() && inputs.isEmpty()) {
3547 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3548 return BAD_VALUE;
3549 }
3550
3551 // open inputs for matching profiles if needed. Direct inputs are also opened to
3552 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3553 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
3554
Eric Laurent1c333e22014-05-20 10:48:17 -07003555 sp<IOProfile> profile = profiles[profile_index];
Eric Laurentd4692962014-05-05 18:13:44 -07003556 // nothing to do if one input is already opened for this profile
3557 size_t input_index;
3558 for (input_index = 0; input_index < mInputs.size(); input_index++) {
3559 desc = mInputs.valueAt(input_index);
3560 if (desc->mProfile == profile) {
Paul McLean9080a4c2015-06-18 08:24:02 -07003561 if (audio_device_is_digital(device)) {
3562 devDesc->importAudioPort(profile);
3563 }
Eric Laurentd4692962014-05-05 18:13:44 -07003564 break;
3565 }
3566 }
3567 if (input_index != mInputs.size()) {
3568 continue;
3569 }
3570
3571 ALOGV("opening input for device 0x%X with params %s", device, address.string());
3572 desc = new AudioInputDescriptor(profile);
3573 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003574 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3575 config.sample_rate = desc->mSamplingRate;
3576 config.channel_mask = desc->mChannelMask;
3577 config.format = desc->mFormat;
3578 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07003579 status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07003580 &input,
3581 &config,
3582 &desc->mDevice,
3583 address,
3584 AUDIO_SOURCE_MIC,
3585 AUDIO_INPUT_FLAG_NONE /*FIXME*/);
Eric Laurentd4692962014-05-05 18:13:44 -07003586
Eric Laurentcf2c0212014-07-25 16:20:43 -07003587 if (status == NO_ERROR) {
3588 desc->mSamplingRate = config.sample_rate;
3589 desc->mChannelMask = config.channel_mask;
3590 desc->mFormat = config.format;
Eric Laurentd4692962014-05-05 18:13:44 -07003591
Eric Laurentd4692962014-05-05 18:13:44 -07003592 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003593 char *param = audio_device_address_to_parameter(device, address);
3594 mpClientInterface->setParameters(input, String8(param));
3595 free(param);
Eric Laurentd4692962014-05-05 18:13:44 -07003596 }
3597
3598 // Here is where we step through and resolve any "dynamic" fields
3599 String8 reply;
3600 char *value;
3601 if (profile->mSamplingRates[0] == 0) {
3602 reply = mpClientInterface->getParameters(input,
3603 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
3604 ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
3605 reply.string());
3606 value = strpbrk((char *)reply.string(), "=");
3607 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003608 profile->loadSamplingRates(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003609 }
3610 }
3611 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3612 reply = mpClientInterface->getParameters(input,
3613 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
3614 ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
3615 value = strpbrk((char *)reply.string(), "=");
3616 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003617 profile->loadFormats(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003618 }
3619 }
3620 if (profile->mChannelMasks[0] == 0) {
3621 reply = mpClientInterface->getParameters(input,
3622 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
3623 ALOGV("checkInputsForDevice() direct input sup channel masks %s",
3624 reply.string());
3625 value = strpbrk((char *)reply.string(), "=");
3626 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003627 profile->loadInChannels(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003628 }
3629 }
3630 if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
3631 ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
3632 ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
3633 ALOGW("checkInputsForDevice() direct input missing param");
3634 mpClientInterface->closeInput(input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003635 input = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003636 }
3637
3638 if (input != 0) {
3639 addInput(input, desc);
3640 }
3641 } // endif input != 0
3642
Eric Laurentcf2c0212014-07-25 16:20:43 -07003643 if (input == AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003644 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
Eric Laurentd4692962014-05-05 18:13:44 -07003645 profiles.removeAt(profile_index);
3646 profile_index--;
3647 } else {
3648 inputs.add(input);
Paul McLean9080a4c2015-06-18 08:24:02 -07003649 if (audio_device_is_digital(device)) {
3650 devDesc->importAudioPort(profile);
3651 }
Eric Laurentd4692962014-05-05 18:13:44 -07003652 ALOGV("checkInputsForDevice(): adding input %d", input);
3653 }
3654 } // end scan profiles
3655
3656 if (profiles.isEmpty()) {
3657 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3658 return BAD_VALUE;
3659 }
3660 } else {
3661 // Disconnect
3662 // check if one opened input is not needed any more after disconnecting one device
3663 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3664 desc = mInputs.valueAt(input_index);
Eric Laurentddbc6652014-11-13 15:13:44 -08003665 if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types() &
3666 ~AUDIO_DEVICE_BIT_IN)) {
Eric Laurentd4692962014-05-05 18:13:44 -07003667 ALOGV("checkInputsForDevice(): disconnecting adding input %d",
3668 mInputs.keyAt(input_index));
3669 inputs.add(mInputs.keyAt(input_index));
3670 }
3671 }
3672 // Clear any profiles associated with the disconnected device.
3673 for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
3674 if (mHwModules[module_index]->mHandle == 0) {
3675 continue;
3676 }
3677 for (size_t profile_index = 0;
3678 profile_index < mHwModules[module_index]->mInputProfiles.size();
3679 profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003680 sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
Paul McLean9080a4c2015-06-18 08:24:02 -07003681 if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07003682 ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
Eric Laurentd4692962014-05-05 18:13:44 -07003683 profile_index, module_index);
3684 if (profile->mSamplingRates[0] == 0) {
3685 profile->mSamplingRates.clear();
3686 profile->mSamplingRates.add(0);
3687 }
3688 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3689 profile->mFormats.clear();
3690 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3691 }
3692 if (profile->mChannelMasks[0] == 0) {
3693 profile->mChannelMasks.clear();
3694 profile->mChannelMasks.add(0);
3695 }
3696 }
3697 }
3698 }
3699 } // end disconnect
3700
3701 return NO_ERROR;
3702}
3703
3704
Eric Laurente0720872014-03-11 09:30:41 -07003705void AudioPolicyManager::closeOutput(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07003706{
3707 ALOGV("closeOutput(%d)", output);
3708
Eric Laurentc75307b2015-03-17 15:29:32 -07003709 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003710 if (outputDesc == NULL) {
3711 ALOGW("closeOutput() unknown output %d", output);
3712 return;
3713 }
François Gaffie036e1e92015-03-19 10:16:24 +01003714 mPolicyMixes.closeOutput(outputDesc);
Eric Laurent275e8e92014-11-30 15:14:47 -08003715
Eric Laurente552edb2014-03-10 17:42:56 -07003716 // look for duplicated outputs connected to the output being removed.
3717 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003718 sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07003719 if (dupOutputDesc->isDuplicated() &&
3720 (dupOutputDesc->mOutput1 == outputDesc ||
3721 dupOutputDesc->mOutput2 == outputDesc)) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003722 sp<AudioOutputDescriptor> outputDesc2;
Eric Laurente552edb2014-03-10 17:42:56 -07003723 if (dupOutputDesc->mOutput1 == outputDesc) {
3724 outputDesc2 = dupOutputDesc->mOutput2;
3725 } else {
3726 outputDesc2 = dupOutputDesc->mOutput1;
3727 }
3728 // As all active tracks on duplicated output will be deleted,
3729 // and as they were also referenced on the other output, the reference
3730 // count for their stream type must be adjusted accordingly on
3731 // the other output.
Eric Laurent3b73df72014-03-11 09:06:29 -07003732 for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
Eric Laurente552edb2014-03-10 17:42:56 -07003733 int refCount = dupOutputDesc->mRefCount[j];
Eric Laurent3b73df72014-03-11 09:06:29 -07003734 outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
Eric Laurente552edb2014-03-10 17:42:56 -07003735 }
3736 audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
3737 ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
3738
3739 mpClientInterface->closeOutput(duplicatedOutput);
François Gaffie53615e22015-03-19 09:24:12 +01003740 removeOutput(duplicatedOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07003741 }
3742 }
3743
Eric Laurent05b90f82014-08-27 15:32:29 -07003744 nextAudioPortGeneration();
3745
3746 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3747 if (index >= 0) {
3748 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3749 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3750 mAudioPatches.removeItemsAt(index);
3751 mpClientInterface->onAudioPatchListUpdate();
3752 }
3753
Eric Laurente552edb2014-03-10 17:42:56 -07003754 AudioParameter param;
3755 param.add(String8("closing"), String8("true"));
3756 mpClientInterface->setParameters(output, param.toString());
3757
3758 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01003759 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003760 mPreviousOutputs = mOutputs;
Eric Laurent05b90f82014-08-27 15:32:29 -07003761}
3762
3763void AudioPolicyManager::closeInput(audio_io_handle_t input)
3764{
3765 ALOGV("closeInput(%d)", input);
3766
3767 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
3768 if (inputDesc == NULL) {
3769 ALOGW("closeInput() unknown input %d", input);
3770 return;
3771 }
3772
Eric Laurent6a94d692014-05-20 11:18:06 -07003773 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07003774
3775 ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
3776 if (index >= 0) {
3777 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3778 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3779 mAudioPatches.removeItemsAt(index);
3780 mpClientInterface->onAudioPatchListUpdate();
3781 }
3782
3783 mpClientInterface->closeInput(input);
3784 mInputs.removeItem(input);
Eric Laurente552edb2014-03-10 17:42:56 -07003785}
3786
Eric Laurentc75307b2015-03-17 15:29:32 -07003787SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
3788 audio_devices_t device,
3789 SwAudioOutputCollection openOutputs)
Eric Laurente552edb2014-03-10 17:42:56 -07003790{
3791 SortedVector<audio_io_handle_t> outputs;
3792
3793 ALOGVV("getOutputsForDevice() device %04x", device);
3794 for (size_t i = 0; i < openOutputs.size(); i++) {
3795 ALOGVV("output %d isDuplicated=%d device=%04x",
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003796 i, openOutputs.valueAt(i)->isDuplicated(),
3797 openOutputs.valueAt(i)->supportedDevices());
Eric Laurente552edb2014-03-10 17:42:56 -07003798 if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
3799 ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
3800 outputs.add(openOutputs.keyAt(i));
3801 }
3802 }
3803 return outputs;
3804}
3805
Eric Laurente0720872014-03-11 09:30:41 -07003806bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
François Gaffie53615e22015-03-19 09:24:12 +01003807 SortedVector<audio_io_handle_t>& outputs2)
Eric Laurente552edb2014-03-10 17:42:56 -07003808{
3809 if (outputs1.size() != outputs2.size()) {
3810 return false;
3811 }
3812 for (size_t i = 0; i < outputs1.size(); i++) {
3813 if (outputs1[i] != outputs2[i]) {
3814 return false;
3815 }
3816 }
3817 return true;
3818}
3819
Eric Laurente0720872014-03-11 09:30:41 -07003820void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
Eric Laurente552edb2014-03-10 17:42:56 -07003821{
3822 audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
3823 audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
3824 SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
3825 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
3826
Jean-Michel Trivife472e22014-12-16 14:23:13 -08003827 // also take into account external policy-related changes: add all outputs which are
3828 // associated with policies in the "before" and "after" output vectors
3829 ALOGVV("checkOutputForStrategy(): policy related outputs");
3830 for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003831 const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
Jean-Michel Trivife472e22014-12-16 14:23:13 -08003832 if (desc != 0 && desc->mPolicyMix != NULL) {
3833 srcOutputs.add(desc->mIoHandle);
3834 ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
3835 }
3836 }
3837 for (size_t i = 0 ; i < mOutputs.size() ; i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003838 const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Jean-Michel Trivife472e22014-12-16 14:23:13 -08003839 if (desc != 0 && desc->mPolicyMix != NULL) {
3840 dstOutputs.add(desc->mIoHandle);
3841 ALOGVV(" new outputs: adding %d", desc->mIoHandle);
3842 }
3843 }
3844
Eric Laurente552edb2014-03-10 17:42:56 -07003845 if (!vectorsEqual(srcOutputs,dstOutputs)) {
3846 ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
3847 strategy, srcOutputs[0], dstOutputs[0]);
3848 // mute strategy while moving tracks from one output to another
3849 for (size_t i = 0; i < srcOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003850 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
François Gaffiead3183e2015-03-18 16:55:35 +01003851 if (isStrategyActive(desc, strategy)) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003852 setStrategyMute(strategy, true, desc);
3853 setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07003854 }
3855 }
3856
3857 // Move effects associated to this strategy from previous output to new output
3858 if (strategy == STRATEGY_MEDIA) {
3859 audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
3860 SortedVector<audio_io_handle_t> moved;
3861 for (size_t i = 0; i < mEffects.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003862 sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
3863 if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
3864 effectDesc->mIo != fxOutput) {
3865 if (moved.indexOf(effectDesc->mIo) < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07003866 ALOGV("checkOutputForStrategy() moving effect %d to output %d",
3867 mEffects.keyAt(i), fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003868 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
Eric Laurente552edb2014-03-10 17:42:56 -07003869 fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003870 moved.add(effectDesc->mIo);
Eric Laurente552edb2014-03-10 17:42:56 -07003871 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07003872 effectDesc->mIo = fxOutput;
Eric Laurente552edb2014-03-10 17:42:56 -07003873 }
3874 }
3875 }
3876 // Move tracks associated to this strategy from previous output to new output
Eric Laurent3b73df72014-03-11 09:06:29 -07003877 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08003878 if (i == AUDIO_STREAM_PATCH) {
3879 continue;
3880 }
Eric Laurent3b73df72014-03-11 09:06:29 -07003881 if (getStrategy((audio_stream_type_t)i) == strategy) {
3882 mpClientInterface->invalidateStream((audio_stream_type_t)i);
Eric Laurente552edb2014-03-10 17:42:56 -07003883 }
3884 }
3885 }
3886}
3887
Eric Laurente0720872014-03-11 09:30:41 -07003888void AudioPolicyManager::checkOutputForAllStrategies()
Eric Laurente552edb2014-03-10 17:42:56 -07003889{
François Gaffie2110e042015-03-24 08:41:51 +01003890 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05003891 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07003892 checkOutputForStrategy(STRATEGY_PHONE);
François Gaffie2110e042015-03-24 08:41:51 +01003893 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05003894 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07003895 checkOutputForStrategy(STRATEGY_SONIFICATION);
3896 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
Eric Laurent223fd5c2014-11-11 13:43:36 -08003897 checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -07003898 checkOutputForStrategy(STRATEGY_MEDIA);
3899 checkOutputForStrategy(STRATEGY_DTMF);
Eric Laurent223fd5c2014-11-11 13:43:36 -08003900 checkOutputForStrategy(STRATEGY_REROUTING);
Eric Laurente552edb2014-03-10 17:42:56 -07003901}
3902
Eric Laurente0720872014-03-11 09:30:41 -07003903void AudioPolicyManager::checkA2dpSuspend()
Eric Laurente552edb2014-03-10 17:42:56 -07003904{
François Gaffie53615e22015-03-19 09:24:12 +01003905 audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
Eric Laurente552edb2014-03-10 17:42:56 -07003906 if (a2dpOutput == 0) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003907 mA2dpSuspended = false;
Eric Laurente552edb2014-03-10 17:42:56 -07003908 return;
3909 }
3910
Eric Laurent3a4311c2014-03-17 12:00:47 -07003911 bool isScoConnected =
Eric Laurentddbc6652014-11-13 15:13:44 -08003912 ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
3913 ~AUDIO_DEVICE_BIT_IN) != 0) ||
3914 ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07003915 // suspend A2DP output if:
3916 // (NOT already suspended) &&
3917 // ((SCO device is connected &&
3918 // (forced usage for communication || for record is SCO))) ||
3919 // (phone state is ringing || in call)
3920 //
3921 // restore A2DP output if:
3922 // (Already suspended) &&
3923 // ((SCO device is NOT connected ||
3924 // (forced usage NOT for communication && NOT for record is SCO))) &&
3925 // (phone state is NOT ringing && NOT in call)
3926 //
3927 if (mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003928 if ((!isScoConnected ||
François Gaffie2110e042015-03-24 08:41:51 +01003929 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) != AUDIO_POLICY_FORCE_BT_SCO) &&
3930 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) != AUDIO_POLICY_FORCE_BT_SCO))) &&
3931 ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
3932 (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003933
3934 mpClientInterface->restoreOutput(a2dpOutput);
3935 mA2dpSuspended = false;
3936 }
3937 } else {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003938 if ((isScoConnected &&
François Gaffie2110e042015-03-24 08:41:51 +01003939 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) ||
3940 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO))) ||
3941 ((mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
3942 (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003943
3944 mpClientInterface->suspendOutput(a2dpOutput);
3945 mA2dpSuspended = true;
3946 }
3947 }
3948}
3949
Eric Laurentc75307b2015-03-17 15:29:32 -07003950audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
3951 bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07003952{
3953 audio_devices_t device = AUDIO_DEVICE_NONE;
3954
Eric Laurent6a94d692014-05-20 11:18:06 -07003955 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3956 if (index >= 0) {
3957 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3958 if (patchDesc->mUid != mUidCached) {
3959 ALOGV("getNewOutputDevice() device %08x forced by patch %d",
3960 outputDesc->device(), outputDesc->mPatchHandle);
3961 return outputDesc->device();
3962 }
3963 }
3964
Eric Laurente552edb2014-03-10 17:42:56 -07003965 // check the following by order of priority to request a routing change if necessary:
Jon Eklund966095e2014-09-09 15:39:49 -05003966 // 1: the strategy enforced audible is active and enforced on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003967 // use device for strategy enforced audible
3968 // 2: we are in call or the strategy phone is active on the output:
3969 // use device for strategy phone
Jon Eklund966095e2014-09-09 15:39:49 -05003970 // 3: the strategy for enforced audible is active but not enforced on the output:
3971 // use the device for strategy enforced audible
Jean-Michel Trivi5de234b2015-07-21 11:42:02 -07003972 // 4: the strategy accessibility is active on the output:
Eric Laurent223fd5c2014-11-11 13:43:36 -08003973 // use device for strategy accessibility
Jean-Michel Trivi5de234b2015-07-21 11:42:02 -07003974 // 5: the strategy sonification is active on the output:
3975 // use device for strategy sonification
3976 // 6: the strategy "respectful" sonification is active on the output:
3977 // use device for strategy "respectful" sonification
Eric Laurent223fd5c2014-11-11 13:43:36 -08003978 // 7: the strategy media is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003979 // use device for strategy media
Eric Laurent223fd5c2014-11-11 13:43:36 -08003980 // 8: the strategy DTMF is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07003981 // use device for strategy DTMF
Eric Laurent223fd5c2014-11-11 13:43:36 -08003982 // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003983 // use device for strategy t-t-s
François Gaffiead3183e2015-03-18 16:55:35 +01003984 if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01003985 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
Eric Laurente552edb2014-03-10 17:42:56 -07003986 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
3987 } else if (isInCall() ||
François Gaffiead3183e2015-03-18 16:55:35 +01003988 isStrategyActive(outputDesc, STRATEGY_PHONE)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003989 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003990 } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
Jon Eklund966095e2014-09-09 15:39:49 -05003991 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
Jean-Michel Trivi5de234b2015-07-21 11:42:02 -07003992 } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
3993 device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003994 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003995 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003996 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003997 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01003998 } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003999 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004000 } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004001 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004002 } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004003 device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004004 } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004005 device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
Eric Laurente552edb2014-03-10 17:42:56 -07004006 }
4007
Eric Laurent1c333e22014-05-20 10:48:17 -07004008 ALOGV("getNewOutputDevice() selected device %x", device);
4009 return device;
4010}
4011
4012audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
4013{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004014 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07004015
4016 ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4017 if (index >= 0) {
4018 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4019 if (patchDesc->mUid != mUidCached) {
4020 ALOGV("getNewInputDevice() device %08x forced by patch %d",
4021 inputDesc->mDevice, inputDesc->mPatchHandle);
4022 return inputDesc->mDevice;
4023 }
4024 }
4025
Eric Laurentc73ca6e2014-12-12 14:34:22 -08004026 audio_devices_t device = getDeviceAndMixForInputSource(inputDesc->mInputSource);
Eric Laurent1c333e22014-05-20 10:48:17 -07004027
Eric Laurente552edb2014-03-10 17:42:56 -07004028 return device;
4029}
4030
Eric Laurente0720872014-03-11 09:30:41 -07004031uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004032 return (uint32_t)getStrategy(stream);
4033}
4034
Eric Laurente0720872014-03-11 09:30:41 -07004035audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004036 // By checking the range of stream before calling getStrategy, we avoid
4037 // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
4038 // and then return STRATEGY_MEDIA, but we want to return the empty set.
Eric Laurent223fd5c2014-11-11 13:43:36 -08004039 if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004040 return AUDIO_DEVICE_NONE;
4041 }
4042 audio_devices_t devices;
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -08004043 routing_strategy strategy = getStrategy(stream);
Eric Laurent6a94d692014-05-20 11:18:06 -07004044 devices = getDeviceForStrategy(strategy, true /*fromCache*/);
4045 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
4046 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004047 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
François Gaffiead3183e2015-03-18 16:55:35 +01004048 if (isStrategyActive(outputDesc, strategy)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004049 devices = outputDesc->device();
4050 break;
4051 }
Eric Laurente552edb2014-03-10 17:42:56 -07004052 }
Jon Eklund11c9fb12014-06-23 14:47:03 -05004053
4054 /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
4055 and doesn't really need to.*/
4056 if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
4057 devices |= AUDIO_DEVICE_OUT_SPEAKER;
4058 devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
4059 }
4060
Eric Laurente552edb2014-03-10 17:42:56 -07004061 return devices;
4062}
4063
François Gaffie2110e042015-03-24 08:41:51 +01004064routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
4065{
Eric Laurent223fd5c2014-11-11 13:43:36 -08004066 ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
François Gaffie2110e042015-03-24 08:41:51 +01004067 return mEngine->getStrategyForStream(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004068}
4069
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004070uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
4071 // flags to strategy mapping
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004072 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4073 return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
4074 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004075 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
4076 return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
4077 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004078 // usage to strategy mapping
François Gaffie2110e042015-03-24 08:41:51 +01004079 return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004080}
4081
Eric Laurente0720872014-03-11 09:30:41 -07004082void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004083 switch(stream) {
Eric Laurent3b73df72014-03-11 09:06:29 -07004084 case AUDIO_STREAM_MUSIC:
Eric Laurente552edb2014-03-10 17:42:56 -07004085 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4086 updateDevicesAndOutputs();
4087 break;
4088 default:
4089 break;
4090 }
4091}
4092
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004093uint32_t AudioPolicyManager::handleEventForBeacon(int event) {
Eric Laurent9459fb02015-08-12 18:36:32 -07004094
4095 // skip beacon mute management if a dedicated TTS output is available
4096 if (mTtsOutputAvailable) {
4097 return 0;
4098 }
4099
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004100 switch(event) {
4101 case STARTING_OUTPUT:
4102 mBeaconMuteRefCount++;
4103 break;
4104 case STOPPING_OUTPUT:
4105 if (mBeaconMuteRefCount > 0) {
4106 mBeaconMuteRefCount--;
4107 }
4108 break;
4109 case STARTING_BEACON:
4110 mBeaconPlayingRefCount++;
4111 break;
4112 case STOPPING_BEACON:
4113 if (mBeaconPlayingRefCount > 0) {
4114 mBeaconPlayingRefCount--;
4115 }
4116 break;
4117 }
4118
4119 if (mBeaconMuteRefCount > 0) {
4120 // any playback causes beacon to be muted
4121 return setBeaconMute(true);
4122 } else {
4123 // no other playback: unmute when beacon starts playing, mute when it stops
4124 return setBeaconMute(mBeaconPlayingRefCount == 0);
4125 }
4126}
4127
4128uint32_t AudioPolicyManager::setBeaconMute(bool mute) {
4129 ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
4130 mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
4131 // keep track of muted state to avoid repeating mute/unmute operations
4132 if (mBeaconMuted != mute) {
4133 // mute/unmute AUDIO_STREAM_TTS on all outputs
4134 ALOGV("\t muting %d", mute);
4135 uint32_t maxLatency = 0;
4136 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004137 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004138 setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
Eric Laurentc75307b2015-03-17 15:29:32 -07004139 desc,
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004140 0 /*delay*/, AUDIO_DEVICE_NONE);
4141 const uint32_t latency = desc->latency() * 2;
4142 if (latency > maxLatency) {
4143 maxLatency = latency;
4144 }
4145 }
4146 mBeaconMuted = mute;
4147 return maxLatency;
4148 }
4149 return 0;
4150}
4151
Eric Laurente0720872014-03-11 09:30:41 -07004152audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
François Gaffie53615e22015-03-19 09:24:12 +01004153 bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07004154{
Paul McLeanaa981192015-03-21 09:55:15 -07004155 // Routing
4156 // see if we have an explicit route
4157 // scan the whole RouteMap, for each entry, convert the stream type to a strategy
4158 // (getStrategy(stream)).
4159 // if the strategy from the stream type in the RouteMap is the same as the argument above,
4160 // and activity count is non-zero
4161 // the device = the device from the descriptor in the RouteMap, and exit.
4162 for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
4163 sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
4164 routing_strategy strat = getStrategy(route->mStreamType);
Eric Laurent093a20c2015-06-11 12:33:29 -07004165 // Special case for accessibility strategy which must follow any strategy it is
4166 // currently remapped to
4167 bool strategyMatch = (strat == strategy) ||
4168 ((strategy == STRATEGY_ACCESSIBILITY) &&
4169 ((mEngine->getStrategyForUsage(
4170 AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY) == strat) ||
4171 (strat == STRATEGY_MEDIA)));
4172 if (strategyMatch && route->isActive()) {
Paul McLeanaa981192015-03-21 09:55:15 -07004173 return route->mDeviceDescriptor->type();
4174 }
4175 }
4176
Eric Laurente552edb2014-03-10 17:42:56 -07004177 if (fromCache) {
4178 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
4179 strategy, mDeviceForStrategy[strategy]);
4180 return mDeviceForStrategy[strategy];
4181 }
François Gaffie2110e042015-03-24 08:41:51 +01004182 return mEngine->getDeviceForStrategy(strategy);
Eric Laurente552edb2014-03-10 17:42:56 -07004183}
4184
Eric Laurente0720872014-03-11 09:30:41 -07004185void AudioPolicyManager::updateDevicesAndOutputs()
Eric Laurente552edb2014-03-10 17:42:56 -07004186{
4187 for (int i = 0; i < NUM_STRATEGIES; i++) {
4188 mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4189 }
4190 mPreviousOutputs = mOutputs;
4191}
4192
Eric Laurent1f2f2232014-06-02 12:01:23 -07004193uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004194 audio_devices_t prevDevice,
4195 uint32_t delayMs)
4196{
4197 // mute/unmute strategies using an incompatible device combination
4198 // if muting, wait for the audio in pcm buffer to be drained before proceeding
4199 // if unmuting, unmute only after the specified delay
4200 if (outputDesc->isDuplicated()) {
4201 return 0;
4202 }
4203
4204 uint32_t muteWaitMs = 0;
4205 audio_devices_t device = outputDesc->device();
Eric Laurent3b73df72014-03-11 09:06:29 -07004206 bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
Eric Laurente552edb2014-03-10 17:42:56 -07004207
4208 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4209 audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
Eric Laurentc75307b2015-03-17 15:29:32 -07004210 curDevice = curDevice & outputDesc->supportedDevices();
Eric Laurente552edb2014-03-10 17:42:56 -07004211 bool mute = shouldMute && (curDevice & device) && (curDevice != device);
4212 bool doMute = false;
4213
4214 if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
4215 doMute = true;
4216 outputDesc->mStrategyMutedByDevice[i] = true;
4217 } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
4218 doMute = true;
4219 outputDesc->mStrategyMutedByDevice[i] = false;
4220 }
Eric Laurent99401132014-05-07 19:48:15 -07004221 if (doMute) {
Eric Laurente552edb2014-03-10 17:42:56 -07004222 for (size_t j = 0; j < mOutputs.size(); j++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004223 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
Eric Laurente552edb2014-03-10 17:42:56 -07004224 // skip output if it does not share any device with current output
4225 if ((desc->supportedDevices() & outputDesc->supportedDevices())
4226 == AUDIO_DEVICE_NONE) {
4227 continue;
4228 }
Eric Laurentc75307b2015-03-17 15:29:32 -07004229 ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x)",
4230 mute ? "muting" : "unmuting", i, curDevice);
4231 setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
François Gaffiead3183e2015-03-18 16:55:35 +01004232 if (isStrategyActive(desc, (routing_strategy)i)) {
Eric Laurent99401132014-05-07 19:48:15 -07004233 if (mute) {
4234 // FIXME: should not need to double latency if volume could be applied
4235 // immediately by the audioflinger mixer. We must account for the delay
4236 // between now and the next time the audioflinger thread for this output
4237 // will process a buffer (which corresponds to one buffer size,
4238 // usually 1/2 or 1/4 of the latency).
4239 if (muteWaitMs < desc->latency() * 2) {
4240 muteWaitMs = desc->latency() * 2;
Eric Laurente552edb2014-03-10 17:42:56 -07004241 }
4242 }
4243 }
4244 }
4245 }
4246 }
4247
Eric Laurent99401132014-05-07 19:48:15 -07004248 // temporary mute output if device selection changes to avoid volume bursts due to
4249 // different per device volumes
4250 if (outputDesc->isActive() && (device != prevDevice)) {
4251 if (muteWaitMs < outputDesc->latency() * 2) {
4252 muteWaitMs = outputDesc->latency() * 2;
4253 }
4254 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
François Gaffiead3183e2015-03-18 16:55:35 +01004255 if (isStrategyActive(outputDesc, (routing_strategy)i)) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004256 setStrategyMute((routing_strategy)i, true, outputDesc);
Eric Laurent99401132014-05-07 19:48:15 -07004257 // do tempMute unmute after twice the mute wait time
Eric Laurentc75307b2015-03-17 15:29:32 -07004258 setStrategyMute((routing_strategy)i, false, outputDesc,
Eric Laurent99401132014-05-07 19:48:15 -07004259 muteWaitMs *2, device);
4260 }
4261 }
4262 }
4263
Eric Laurente552edb2014-03-10 17:42:56 -07004264 // wait for the PCM output buffers to empty before proceeding with the rest of the command
4265 if (muteWaitMs > delayMs) {
4266 muteWaitMs -= delayMs;
4267 usleep(muteWaitMs * 1000);
4268 return muteWaitMs;
4269 }
4270 return 0;
4271}
4272
Eric Laurentc75307b2015-03-17 15:29:32 -07004273uint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004274 audio_devices_t device,
4275 bool force,
Eric Laurent6a94d692014-05-20 11:18:06 -07004276 int delayMs,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004277 audio_patch_handle_t *patchHandle,
4278 const char* address)
Eric Laurente552edb2014-03-10 17:42:56 -07004279{
Eric Laurentc75307b2015-03-17 15:29:32 -07004280 ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004281 AudioParameter param;
4282 uint32_t muteWaitMs;
4283
4284 if (outputDesc->isDuplicated()) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004285 muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs);
4286 muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004287 return muteWaitMs;
4288 }
4289 // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
4290 // output profile
Eric Laurentc75307b2015-03-17 15:29:32 -07004291 if ((device != AUDIO_DEVICE_NONE) &&
4292 ((device & outputDesc->supportedDevices()) == 0)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004293 return 0;
4294 }
4295
4296 // filter devices according to output selected
Eric Laurentc75307b2015-03-17 15:29:32 -07004297 device = (audio_devices_t)(device & outputDesc->supportedDevices());
Eric Laurente552edb2014-03-10 17:42:56 -07004298
4299 audio_devices_t prevDevice = outputDesc->mDevice;
4300
Paul McLeanaa981192015-03-21 09:55:15 -07004301 ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004302
4303 if (device != AUDIO_DEVICE_NONE) {
4304 outputDesc->mDevice = device;
4305 }
4306 muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
4307
4308 // Do not change the routing if:
Eric Laurentb80a2a82014-10-27 16:07:59 -07004309 // the requested device is AUDIO_DEVICE_NONE
4310 // OR the requested device is the same as current device
4311 // AND force is not specified
4312 // AND the output is connected by a valid audio patch.
Eric Laurente552edb2014-03-10 17:42:56 -07004313 // Doing this check here allows the caller to call setOutputDevice() without conditions
Paul McLeanaa981192015-03-21 09:55:15 -07004314 if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
4315 !force &&
4316 outputDesc->mPatchHandle != 0) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004317 ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
Eric Laurente552edb2014-03-10 17:42:56 -07004318 return muteWaitMs;
4319 }
4320
4321 ALOGV("setOutputDevice() changing device");
Eric Laurent1c333e22014-05-20 10:48:17 -07004322
Eric Laurente552edb2014-03-10 17:42:56 -07004323 // do the routing
Eric Laurent1c333e22014-05-20 10:48:17 -07004324 if (device == AUDIO_DEVICE_NONE) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004325 resetOutputDevice(outputDesc, delayMs, NULL);
Eric Laurent1c333e22014-05-20 10:48:17 -07004326 } else {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004327 DeviceVector deviceList = (address == NULL) ?
4328 mAvailableOutputDevices.getDevicesFromType(device)
4329 : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
Eric Laurent1c333e22014-05-20 10:48:17 -07004330 if (!deviceList.isEmpty()) {
4331 struct audio_patch patch;
4332 outputDesc->toAudioPortConfig(&patch.sources[0]);
4333 patch.num_sources = 1;
4334 patch.num_sinks = 0;
4335 for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
4336 deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
Eric Laurent1c333e22014-05-20 10:48:17 -07004337 patch.num_sinks++;
4338 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004339 ssize_t index;
4340 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
4341 index = mAudioPatches.indexOfKey(*patchHandle);
4342 } else {
4343 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
4344 }
4345 sp< AudioPatch> patchDesc;
4346 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
4347 if (index >= 0) {
4348 patchDesc = mAudioPatches.valueAt(index);
4349 afPatchHandle = patchDesc->mAfPatchHandle;
4350 }
4351
Eric Laurent1c333e22014-05-20 10:48:17 -07004352 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07004353 &afPatchHandle,
4354 delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07004355 ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
4356 "num_sources %d num_sinks %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004357 status, afPatchHandle, patch.num_sources, patch.num_sinks);
Eric Laurent1c333e22014-05-20 10:48:17 -07004358 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004359 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01004360 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07004361 addAudioPatch(patchDesc->mHandle, patchDesc);
4362 } else {
4363 patchDesc->mPatch = patch;
4364 }
4365 patchDesc->mAfPatchHandle = afPatchHandle;
4366 patchDesc->mUid = mUidCached;
4367 if (patchHandle) {
4368 *patchHandle = patchDesc->mHandle;
4369 }
4370 outputDesc->mPatchHandle = patchDesc->mHandle;
4371 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004372 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004373 }
4374 }
bryant_liuf5e7e792014-08-19 20:07:05 +08004375
4376 // inform all input as well
4377 for (size_t i = 0; i < mInputs.size(); i++) {
4378 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
François Gaffie53615e22015-03-19 09:24:12 +01004379 if (!is_virtual_input_device(inputDescriptor->mDevice)) {
bryant_liuf5e7e792014-08-19 20:07:05 +08004380 AudioParameter inputCmd = AudioParameter();
4381 ALOGV("%s: inform input %d of device:%d", __func__,
4382 inputDescriptor->mIoHandle, device);
4383 inputCmd.addInt(String8(AudioParameter::keyRouting),device);
4384 mpClientInterface->setParameters(inputDescriptor->mIoHandle,
4385 inputCmd.toString(),
4386 delayMs);
4387 }
4388 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004389 }
Eric Laurente552edb2014-03-10 17:42:56 -07004390
4391 // update stream volumes according to new device
Eric Laurentc75307b2015-03-17 15:29:32 -07004392 applyStreamVolumes(outputDesc, device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004393
4394 return muteWaitMs;
4395}
4396
Eric Laurentc75307b2015-03-17 15:29:32 -07004397status_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurent6a94d692014-05-20 11:18:06 -07004398 int delayMs,
4399 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004400{
Eric Laurent6a94d692014-05-20 11:18:06 -07004401 ssize_t index;
4402 if (patchHandle) {
4403 index = mAudioPatches.indexOfKey(*patchHandle);
4404 } else {
4405 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
4406 }
4407 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004408 return INVALID_OPERATION;
4409 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004410 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4411 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07004412 ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
4413 outputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004414 removeAudioPatch(patchDesc->mHandle);
4415 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004416 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004417 return status;
4418}
4419
4420status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
4421 audio_devices_t device,
Eric Laurent6a94d692014-05-20 11:18:06 -07004422 bool force,
4423 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004424{
4425 status_t status = NO_ERROR;
4426
Eric Laurent1f2f2232014-06-02 12:01:23 -07004427 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07004428 if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
4429 inputDesc->mDevice = device;
4430
4431 DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
4432 if (!deviceList.isEmpty()) {
4433 struct audio_patch patch;
4434 inputDesc->toAudioPortConfig(&patch.sinks[0]);
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004435 // AUDIO_SOURCE_HOTWORD is for internal use only:
4436 // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07004437 if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
4438 !inputDesc->mIsSoundTrigger) {
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004439 patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
4440 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004441 patch.num_sinks = 1;
4442 //only one input device for now
4443 deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
Eric Laurent1c333e22014-05-20 10:48:17 -07004444 patch.num_sources = 1;
Eric Laurent6a94d692014-05-20 11:18:06 -07004445 ssize_t index;
4446 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
4447 index = mAudioPatches.indexOfKey(*patchHandle);
4448 } else {
4449 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4450 }
4451 sp< AudioPatch> patchDesc;
4452 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
4453 if (index >= 0) {
4454 patchDesc = mAudioPatches.valueAt(index);
4455 afPatchHandle = patchDesc->mAfPatchHandle;
4456 }
4457
Eric Laurent1c333e22014-05-20 10:48:17 -07004458 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07004459 &afPatchHandle,
Eric Laurent1c333e22014-05-20 10:48:17 -07004460 0);
4461 ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004462 status, afPatchHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -07004463 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004464 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01004465 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07004466 addAudioPatch(patchDesc->mHandle, patchDesc);
4467 } else {
4468 patchDesc->mPatch = patch;
4469 }
4470 patchDesc->mAfPatchHandle = afPatchHandle;
4471 patchDesc->mUid = mUidCached;
4472 if (patchHandle) {
4473 *patchHandle = patchDesc->mHandle;
4474 }
4475 inputDesc->mPatchHandle = patchDesc->mHandle;
4476 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004477 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004478 }
4479 }
4480 }
4481 return status;
4482}
4483
Eric Laurent6a94d692014-05-20 11:18:06 -07004484status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
4485 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004486{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004487 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07004488 ssize_t index;
4489 if (patchHandle) {
4490 index = mAudioPatches.indexOfKey(*patchHandle);
4491 } else {
4492 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4493 }
4494 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004495 return INVALID_OPERATION;
4496 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004497 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4498 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent1c333e22014-05-20 10:48:17 -07004499 ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
4500 inputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004501 removeAudioPatch(patchDesc->mHandle);
4502 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004503 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004504 return status;
4505}
4506
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -08004507sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +01004508 String8 address,
4509 uint32_t& samplingRate,
Andy Hungf129b032015-04-07 13:45:50 -07004510 audio_format_t& format,
4511 audio_channel_mask_t& channelMask,
François Gaffie53615e22015-03-19 09:24:12 +01004512 audio_input_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07004513{
4514 // Choose an input profile based on the requested capture parameters: select the first available
4515 // profile supporting all requested parameters.
Andy Hungf129b032015-04-07 13:45:50 -07004516 //
4517 // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
4518 // the best matching profile, not the first one.
Eric Laurente552edb2014-03-10 17:42:56 -07004519
4520 for (size_t i = 0; i < mHwModules.size(); i++)
4521 {
4522 if (mHwModules[i]->mHandle == 0) {
4523 continue;
4524 }
4525 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
4526 {
Eric Laurent1c333e22014-05-20 10:48:17 -07004527 sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07004528 // profile->log();
Eric Laurent275e8e92014-11-30 15:14:47 -08004529 if (profile->isCompatibleProfile(device, address, samplingRate,
Glenn Kastencbd48022014-07-24 13:46:44 -07004530 &samplingRate /*updatedSamplingRate*/,
Andy Hungf129b032015-04-07 13:45:50 -07004531 format,
4532 &format /*updatedFormat*/,
4533 channelMask,
4534 &channelMask /*updatedChannelMask*/,
4535 (audio_output_flags_t) flags)) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004536
Eric Laurente552edb2014-03-10 17:42:56 -07004537 return profile;
4538 }
4539 }
4540 }
4541 return NULL;
4542}
4543
Eric Laurentc73ca6e2014-12-12 14:34:22 -08004544
4545audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
François Gaffie53615e22015-03-19 09:24:12 +01004546 AudioMix **policyMix)
Eric Laurente552edb2014-03-10 17:42:56 -07004547{
François Gaffie036e1e92015-03-19 10:16:24 +01004548 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
4549 audio_devices_t selectedDeviceFromMix =
4550 mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08004551
François Gaffie036e1e92015-03-19 10:16:24 +01004552 if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
4553 return selectedDeviceFromMix;
Eric Laurent275e8e92014-11-30 15:14:47 -08004554 }
Eric Laurentc73ca6e2014-12-12 14:34:22 -08004555 return getDeviceForInputSource(inputSource);
4556}
4557
4558audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
4559{
Paul McLean466dc8e2015-04-17 13:15:36 -06004560 for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
4561 sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07004562 if (inputSource == route->mSource && route->isActive()) {
Paul McLean466dc8e2015-04-17 13:15:36 -06004563 return route->mDeviceDescriptor->type();
4564 }
4565 }
4566
4567 return mEngine->getDeviceForInputSource(inputSource);
Eric Laurente552edb2014-03-10 17:42:56 -07004568}
4569
Eric Laurente0720872014-03-11 09:30:41 -07004570float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07004571 int index,
4572 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004573{
Eric Laurentffbc80f2015-03-18 18:30:19 -07004574 float volumeDb = mEngine->volIndexToDb(Volume::getDeviceCategory(device), stream, index);
Eric Laurente552edb2014-03-10 17:42:56 -07004575
4576 // if a headset is connected, apply the following rules to ring tones and notifications
4577 // to avoid sound level bursts in user's ears:
4578 // - always attenuate ring tones and notifications volume by 6dB
4579 // - if music is playing, always limit the volume to current music volume,
4580 // with a minimum threshold at -36dB so that notification is always perceived.
Eric Laurent3b73df72014-03-11 09:06:29 -07004581 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004582 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
4583 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
4584 AUDIO_DEVICE_OUT_WIRED_HEADSET |
4585 AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
4586 ((stream_strategy == STRATEGY_SONIFICATION)
4587 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
Eric Laurent3b73df72014-03-11 09:06:29 -07004588 || (stream == AUDIO_STREAM_SYSTEM)
Eric Laurente552edb2014-03-10 17:42:56 -07004589 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01004590 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
4591 mStreams.canBeMuted(stream)) {
Eric Laurentffbc80f2015-03-18 18:30:19 -07004592 volumeDb += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
Eric Laurente552edb2014-03-10 17:42:56 -07004593 // when the phone is ringing we must consider that music could have been paused just before
4594 // by the music application and behave as if music was active if the last music track was
4595 // just stopped
Eric Laurent3b73df72014-03-11 09:06:29 -07004596 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
Eric Laurente552edb2014-03-10 17:42:56 -07004597 mLimitRingtoneVolume) {
4598 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
Eric Laurentffbc80f2015-03-18 18:30:19 -07004599 float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
4600 mStreams.valueFor(AUDIO_STREAM_MUSIC).getVolumeIndex(musicDevice),
Eric Laurente552edb2014-03-10 17:42:56 -07004601 musicDevice);
Eric Laurentffbc80f2015-03-18 18:30:19 -07004602 float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
4603 musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
4604 if (volumeDb > minVolDB) {
4605 volumeDb = minVolDB;
4606 ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
Eric Laurente552edb2014-03-10 17:42:56 -07004607 }
4608 }
4609 }
4610
Eric Laurentffbc80f2015-03-18 18:30:19 -07004611 return volumeDb;
Eric Laurente552edb2014-03-10 17:42:56 -07004612}
4613
Eric Laurente0720872014-03-11 09:30:41 -07004614status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07004615 int index,
4616 const sp<AudioOutputDescriptor>& outputDesc,
4617 audio_devices_t device,
4618 int delayMs,
4619 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07004620{
Eric Laurente552edb2014-03-10 17:42:56 -07004621 // do not change actual stream volume if the stream is muted
Eric Laurentc75307b2015-03-17 15:29:32 -07004622 if (outputDesc->mMuteCount[stream] != 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07004623 ALOGVV("checkAndSetVolume() stream %d muted count %d",
Eric Laurentc75307b2015-03-17 15:29:32 -07004624 stream, outputDesc->mMuteCount[stream]);
Eric Laurente552edb2014-03-10 17:42:56 -07004625 return NO_ERROR;
4626 }
François Gaffie2110e042015-03-24 08:41:51 +01004627 audio_policy_forced_cfg_t forceUseForComm =
4628 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
Eric Laurente552edb2014-03-10 17:42:56 -07004629 // do not change in call volume if bluetooth is connected and vice versa
François Gaffie2110e042015-03-24 08:41:51 +01004630 if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
4631 (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004632 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
François Gaffie2110e042015-03-24 08:41:51 +01004633 stream, forceUseForComm);
Eric Laurente552edb2014-03-10 17:42:56 -07004634 return INVALID_OPERATION;
4635 }
4636
Eric Laurentc75307b2015-03-17 15:29:32 -07004637 if (device == AUDIO_DEVICE_NONE) {
4638 device = outputDesc->device();
4639 }
Eric Laurent275e8e92014-11-30 15:14:47 -08004640
Eric Laurentffbc80f2015-03-18 18:30:19 -07004641 float volumeDb = computeVolume(stream, index, device);
Eric Laurentc75307b2015-03-17 15:29:32 -07004642 if (outputDesc->isFixedVolume(device)) {
Eric Laurentffbc80f2015-03-18 18:30:19 -07004643 volumeDb = 0.0f;
Eric Laurent275e8e92014-11-30 15:14:47 -08004644 }
Eric Laurentc75307b2015-03-17 15:29:32 -07004645
Eric Laurentffbc80f2015-03-18 18:30:19 -07004646 outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
Eric Laurente552edb2014-03-10 17:42:56 -07004647
Eric Laurent3b73df72014-03-11 09:06:29 -07004648 if (stream == AUDIO_STREAM_VOICE_CALL ||
4649 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
Eric Laurente552edb2014-03-10 17:42:56 -07004650 float voiceVolume;
4651 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
Eric Laurent3b73df72014-03-11 09:06:29 -07004652 if (stream == AUDIO_STREAM_VOICE_CALL) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004653 voiceVolume = (float)index/(float)mStreams.valueFor(stream).getVolumeIndexMax();
Eric Laurente552edb2014-03-10 17:42:56 -07004654 } else {
4655 voiceVolume = 1.0;
4656 }
4657
Eric Laurentc75307b2015-03-17 15:29:32 -07004658 if (voiceVolume != mLastVoiceVolume && outputDesc == mPrimaryOutput) {
Eric Laurente552edb2014-03-10 17:42:56 -07004659 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
4660 mLastVoiceVolume = voiceVolume;
4661 }
4662 }
4663
4664 return NO_ERROR;
4665}
4666
Eric Laurentc75307b2015-03-17 15:29:32 -07004667void AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
4668 audio_devices_t device,
4669 int delayMs,
4670 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07004671{
Eric Laurentc75307b2015-03-17 15:29:32 -07004672 ALOGVV("applyStreamVolumes() for device %08x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07004673
Eric Laurent3b73df72014-03-11 09:06:29 -07004674 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004675 if (stream == AUDIO_STREAM_PATCH) {
4676 continue;
4677 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004678 checkAndSetVolume((audio_stream_type_t)stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07004679 mStreams.valueFor((audio_stream_type_t)stream).getVolumeIndex(device),
4680 outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004681 device,
4682 delayMs,
4683 force);
4684 }
4685}
4686
Eric Laurente0720872014-03-11 09:30:41 -07004687void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
Eric Laurentc75307b2015-03-17 15:29:32 -07004688 bool on,
4689 const sp<AudioOutputDescriptor>& outputDesc,
4690 int delayMs,
4691 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004692{
Eric Laurent72249d52015-06-08 11:12:15 -07004693 ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
4694 strategy, on, outputDesc->getId());
Eric Laurent3b73df72014-03-11 09:06:29 -07004695 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004696 if (stream == AUDIO_STREAM_PATCH) {
4697 continue;
4698 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004699 if (getStrategy((audio_stream_type_t)stream) == strategy) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004700 setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
Eric Laurente552edb2014-03-10 17:42:56 -07004701 }
4702 }
4703}
4704
Eric Laurente0720872014-03-11 09:30:41 -07004705void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07004706 bool on,
4707 const sp<AudioOutputDescriptor>& outputDesc,
4708 int delayMs,
4709 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004710{
Eric Laurentc75307b2015-03-17 15:29:32 -07004711 const StreamDescriptor& streamDesc = mStreams.valueFor(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004712 if (device == AUDIO_DEVICE_NONE) {
4713 device = outputDesc->device();
4714 }
4715
Eric Laurentc75307b2015-03-17 15:29:32 -07004716 ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
4717 stream, on, outputDesc->mMuteCount[stream], device);
Eric Laurente552edb2014-03-10 17:42:56 -07004718
4719 if (on) {
4720 if (outputDesc->mMuteCount[stream] == 0) {
François Gaffiedfd74092015-03-19 12:10:59 +01004721 if (streamDesc.canBeMuted() &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004722 ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
François Gaffie2110e042015-03-24 08:41:51 +01004723 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004724 checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004725 }
4726 }
4727 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
4728 outputDesc->mMuteCount[stream]++;
4729 } else {
4730 if (outputDesc->mMuteCount[stream] == 0) {
4731 ALOGV("setStreamMute() unmuting non muted stream!");
4732 return;
4733 }
4734 if (--outputDesc->mMuteCount[stream] == 0) {
4735 checkAndSetVolume(stream,
4736 streamDesc.getVolumeIndex(device),
Eric Laurentc75307b2015-03-17 15:29:32 -07004737 outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004738 device,
4739 delayMs);
4740 }
4741 }
4742}
4743
Eric Laurente0720872014-03-11 09:30:41 -07004744void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07004745 bool starting, bool stateChange)
Eric Laurente552edb2014-03-10 17:42:56 -07004746{
Eric Laurent87ffa392015-05-22 10:32:38 -07004747 if(!hasPrimaryOutput()) {
4748 return;
4749 }
4750
Eric Laurente552edb2014-03-10 17:42:56 -07004751 // if the stream pertains to sonification strategy and we are in call we must
4752 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
4753 // in the device used for phone strategy and play the tone if the selected device does not
4754 // interfere with the device used for phone strategy
4755 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
4756 // many times as there are active tracks on the output
Eric Laurent3b73df72014-03-11 09:06:29 -07004757 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004758 if ((stream_strategy == STRATEGY_SONIFICATION) ||
4759 ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004760 sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
Eric Laurente552edb2014-03-10 17:42:56 -07004761 ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
4762 stream, starting, outputDesc->mDevice, stateChange);
4763 if (outputDesc->mRefCount[stream]) {
4764 int muteCount = 1;
4765 if (stateChange) {
4766 muteCount = outputDesc->mRefCount[stream];
4767 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004768 if (audio_is_low_visibility(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004769 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
4770 for (int i = 0; i < muteCount; i++) {
4771 setStreamMute(stream, starting, mPrimaryOutput);
4772 }
4773 } else {
4774 ALOGV("handleIncallSonification() high visibility");
4775 if (outputDesc->device() &
4776 getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
4777 ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
4778 for (int i = 0; i < muteCount; i++) {
4779 setStreamMute(stream, starting, mPrimaryOutput);
4780 }
4781 }
4782 if (starting) {
Eric Laurent3b73df72014-03-11 09:06:29 -07004783 mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
4784 AUDIO_STREAM_VOICE_CALL);
Eric Laurente552edb2014-03-10 17:42:56 -07004785 } else {
4786 mpClientInterface->stopTone();
4787 }
4788 }
4789 }
4790 }
4791}
4792
Paul McLeanaa981192015-03-21 09:55:15 -07004793
Paul McLean466dc8e2015-04-17 13:15:36 -06004794
Eric Laurente0720872014-03-11 09:30:41 -07004795void AudioPolicyManager::defaultAudioPolicyConfig(void)
Eric Laurente552edb2014-03-10 17:42:56 -07004796{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004797 sp<HwModule> module;
Eric Laurent1c333e22014-05-20 10:48:17 -07004798 sp<IOProfile> profile;
Paul McLeane743a472015-01-28 11:07:31 -08004799 sp<DeviceDescriptor> defaultInputDevice =
Eric Laurent7288ab82015-05-06 18:44:02 -07004800 new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004801 mAvailableOutputDevices.add(mDefaultOutputDevice);
4802 mAvailableInputDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004803
4804 module = new HwModule("primary");
4805
Eric Laurent322b4d22015-04-03 15:57:54 -07004806 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE);
4807 profile->attach(module);
Eric Laurente552edb2014-03-10 17:42:56 -07004808 profile->mSamplingRates.add(44100);
4809 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4810 profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004811 profile->mSupportedDevices.add(mDefaultOutputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004812 profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
4813 module->mOutputProfiles.add(profile);
4814
Eric Laurent322b4d22015-04-03 15:57:54 -07004815 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK);
4816 profile->attach(module);
Eric Laurente552edb2014-03-10 17:42:56 -07004817 profile->mSamplingRates.add(8000);
4818 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
4819 profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07004820 profile->mSupportedDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004821 module->mInputProfiles.add(profile);
4822
4823 mHwModules.add(module);
4824}
4825
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004826audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
4827{
4828 // flags to stream type mapping
4829 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
4830 return AUDIO_STREAM_ENFORCED_AUDIBLE;
4831 }
4832 if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
4833 return AUDIO_STREAM_BLUETOOTH_SCO;
4834 }
Jean-Michel Trivi79ad4382015-01-29 10:49:39 -08004835 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4836 return AUDIO_STREAM_TTS;
4837 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004838
4839 // usage to stream type mapping
4840 switch (attr->usage) {
4841 case AUDIO_USAGE_MEDIA:
4842 case AUDIO_USAGE_GAME:
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004843 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
4844 return AUDIO_STREAM_MUSIC;
Eric Laurent223fd5c2014-11-11 13:43:36 -08004845 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
Eric Laurente83b55d2014-11-14 10:06:21 -08004846 if (isStreamActive(AUDIO_STREAM_ALARM)) {
4847 return AUDIO_STREAM_ALARM;
4848 }
4849 if (isStreamActive(AUDIO_STREAM_RING)) {
4850 return AUDIO_STREAM_RING;
4851 }
4852 if (isInCall()) {
4853 return AUDIO_STREAM_VOICE_CALL;
4854 }
Eric Laurent223fd5c2014-11-11 13:43:36 -08004855 return AUDIO_STREAM_ACCESSIBILITY;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004856 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
4857 return AUDIO_STREAM_SYSTEM;
4858 case AUDIO_USAGE_VOICE_COMMUNICATION:
4859 return AUDIO_STREAM_VOICE_CALL;
4860
4861 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
4862 return AUDIO_STREAM_DTMF;
4863
4864 case AUDIO_USAGE_ALARM:
4865 return AUDIO_STREAM_ALARM;
4866 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
4867 return AUDIO_STREAM_RING;
4868
4869 case AUDIO_USAGE_NOTIFICATION:
4870 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
4871 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
4872 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
4873 case AUDIO_USAGE_NOTIFICATION_EVENT:
4874 return AUDIO_STREAM_NOTIFICATION;
4875
4876 case AUDIO_USAGE_UNKNOWN:
4877 default:
4878 return AUDIO_STREAM_MUSIC;
4879 }
4880}
Eric Laurente83b55d2014-11-14 10:06:21 -08004881
François Gaffie53615e22015-03-19 09:24:12 +01004882bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
4883{
Eric Laurente83b55d2014-11-14 10:06:21 -08004884 // has flags that map to a strategy?
4885 if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
4886 return true;
4887 }
4888
4889 // has known usage?
4890 switch (paa->usage) {
4891 case AUDIO_USAGE_UNKNOWN:
4892 case AUDIO_USAGE_MEDIA:
4893 case AUDIO_USAGE_VOICE_COMMUNICATION:
4894 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
4895 case AUDIO_USAGE_ALARM:
4896 case AUDIO_USAGE_NOTIFICATION:
4897 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
4898 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
4899 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
4900 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
4901 case AUDIO_USAGE_NOTIFICATION_EVENT:
4902 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
4903 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
4904 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
4905 case AUDIO_USAGE_GAME:
Eric Laurent275e8e92014-11-30 15:14:47 -08004906 case AUDIO_USAGE_VIRTUAL_SOURCE:
Eric Laurente83b55d2014-11-14 10:06:21 -08004907 break;
4908 default:
4909 return false;
4910 }
4911 return true;
4912}
4913
François Gaffiead3183e2015-03-18 16:55:35 +01004914bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor> outputDesc,
4915 routing_strategy strategy, uint32_t inPastMs,
4916 nsecs_t sysTime) const
4917{
4918 if ((sysTime == 0) && (inPastMs != 0)) {
4919 sysTime = systemTime();
4920 }
4921 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
4922 if (i == AUDIO_STREAM_PATCH) {
4923 continue;
4924 }
4925 if (((getStrategy((audio_stream_type_t)i) == strategy) ||
4926 (NUM_STRATEGIES == strategy)) &&
4927 outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
4928 return true;
4929 }
4930 }
4931 return false;
4932}
4933
François Gaffie2110e042015-03-24 08:41:51 +01004934audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
4935{
4936 return mEngine->getForceUse(usage);
4937}
4938
4939bool AudioPolicyManager::isInCall()
4940{
4941 return isStateInCall(mEngine->getPhoneState());
4942}
4943
4944bool AudioPolicyManager::isStateInCall(int state)
4945{
4946 return is_state_in_call(state);
4947}
4948
Eric Laurente552edb2014-03-10 17:42:56 -07004949}; // namespace android