blob: b646c8ebda45348078895bf1543e3bcdc7f8128e [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 Trivi5ac8cd42016-03-24 16:35:36 -070017#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
Jaekyun Seok0d4a6af2017-02-17 17:10:17 +090027#define AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH 128
28#define AUDIO_POLICY_XML_CONFIG_FILE_NAME "audio_policy_configuration.xml"
Petri Gyntherf497f292018-04-17 18:46:10 -070029#define AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME \
30 "audio_policy_configuration_a2dp_offload_disabled.xml"
François Gaffief4ad6e52015-11-19 16:59:57 +010031
Eric Laurentd4692962014-05-05 18:13:44 -070032#include <inttypes.h>
Eric Laurente552edb2014-03-10 17:42:56 -070033#include <math.h>
Eric Laurentd4692962014-05-05 18:13:44 -070034
François Gaffie2110e042015-03-24 08:41:51 +010035#include <AudioPolicyManagerInterface.h>
36#include <AudioPolicyEngineInstance.h>
Mathias Agopian05d19b02017-02-28 16:28:19 -080037#include <cutils/atomic.h>
Eric Laurente552edb2014-03-10 17:42:56 -070038#include <cutils/properties.h>
Eric Laurentd4692962014-05-05 18:13:44 -070039#include <utils/Log.h>
Eric Laurent3b73df72014-03-11 09:06:29 -070040#include <media/AudioParameter.h>
Eric Laurente83b55d2014-11-14 10:06:21 -080041#include <media/AudioPolicyHelper.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070042#include <soundtrigger/SoundTrigger.h>
Mikhail Naganovcbc8f612016-10-11 18:05:13 -070043#include <system/audio.h>
Mikhail Naganov9ee05402016-10-13 15:58:17 -070044#include <audio_policy_conf.h>
Eric Laurentd4692962014-05-05 18:13:44 -070045#include "AudioPolicyManager.h"
François Gaffied1ab2bd2015-12-02 18:20:06 +010046#ifndef USE_XML_AUDIO_POLICY_CONF
François Gaffie53615e22015-03-19 09:24:12 +010047#include <ConfigParsingUtils.h>
François Gaffied1ab2bd2015-12-02 18:20:06 +010048#include <StreamDescriptor.h>
François Gaffief4ad6e52015-11-19 16:59:57 +010049#endif
François Gaffied1ab2bd2015-12-02 18:20:06 +010050#include <Serializer.h>
François Gaffiea8ecc2c2015-11-09 16:10:40 +010051#include "TypeConverter.h"
François Gaffie53615e22015-03-19 09:24:12 +010052#include <policy.h>
Eric Laurente552edb2014-03-10 17:42:56 -070053
Eric Laurent3b73df72014-03-11 09:06:29 -070054namespace android {
Eric Laurente552edb2014-03-10 17:42:56 -070055
Eric Laurentdc462862016-07-19 12:29:53 -070056//FIXME: workaround for truncated touch sounds
57// to be removed when the problem is handled by system UI
58#define TOUCH_SOUND_FIXED_DELAY_MS 100
Jean-Michel Trivi719a9872017-08-05 13:51:35 -070059
60// Largest difference in dB on earpiece in call between the voice volume and another
61// media / notification / system volume.
62constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;
63
Eric Laurente552edb2014-03-10 17:42:56 -070064// ----------------------------------------------------------------------------
65// AudioPolicyInterface implementation
66// ----------------------------------------------------------------------------
67
Eric Laurente0720872014-03-11 09:30:41 -070068status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
Paul McLeane743a472015-01-28 11:07:31 -080069 audio_policy_dev_state_t state,
70 const char *device_address,
71 const char *device_name)
Eric Laurente552edb2014-03-10 17:42:56 -070072{
Paul McLeane743a472015-01-28 11:07:31 -080073 return setDeviceConnectionStateInt(device, state, device_address, device_name);
Eric Laurentc73ca6e2014-12-12 14:34:22 -080074}
75
François Gaffie44481e72016-04-20 07:49:57 +020076void AudioPolicyManager::broadcastDeviceConnectionState(audio_devices_t device,
77 audio_policy_dev_state_t state,
78 const String8 &device_address)
79{
80 AudioParameter param(device_address);
81 const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
Mikhail Naganov388360c2016-10-17 17:09:41 -070082 AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect);
François Gaffie44481e72016-04-20 07:49:57 +020083 param.addInt(key, device);
84 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
85}
86
Eric Laurentc73ca6e2014-12-12 14:34:22 -080087status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device,
Eric Laurenta1d525f2015-01-29 13:36:45 -080088 audio_policy_dev_state_t state,
Paul McLeane743a472015-01-28 11:07:31 -080089 const char *device_address,
90 const char *device_name)
Eric Laurentc73ca6e2014-12-12 14:34:22 -080091{
Paul McLeane743a472015-01-28 11:07:31 -080092 ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
93- device, state, device_address, device_name);
Eric Laurente552edb2014-03-10 17:42:56 -070094
95 // connect/disconnect only 1 device at a time
96 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
97
François Gaffie53615e22015-03-19 09:24:12 +010098 sp<DeviceDescriptor> devDesc =
99 mHwModules.getDeviceDescriptor(device, device_address, device_name);
Paul McLeane743a472015-01-28 11:07:31 -0800100
Eric Laurente552edb2014-03-10 17:42:56 -0700101 // handle output devices
102 if (audio_is_output_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700103 SortedVector <audio_io_handle_t> outputs;
104
Eric Laurent3a4311c2014-03-17 12:00:47 -0700105 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
106
Eric Laurente552edb2014-03-10 17:42:56 -0700107 // save a copy of the opened output descriptors before any output is opened or closed
108 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
109 mPreviousOutputs = mOutputs;
Eric Laurente552edb2014-03-10 17:42:56 -0700110 switch (state)
111 {
112 // handle output device connection
Eric Laurent3ae5f312015-02-03 17:12:08 -0800113 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700114 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700115 ALOGW("setDeviceConnectionState() device already connected: %x", device);
116 return INVALID_OPERATION;
117 }
118 ALOGV("setDeviceConnectionState() connecting device %x", device);
119
Eric Laurente552edb2014-03-10 17:42:56 -0700120 // register new device as available
Eric Laurent3a4311c2014-03-17 12:00:47 -0700121 index = mAvailableOutputDevices.add(devDesc);
122 if (index >= 0) {
François Gaffie53615e22015-03-19 09:24:12 +0100123 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurentcf817a22014-08-04 20:36:31 -0700124 if (module == 0) {
125 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
126 device);
127 mAvailableOutputDevices.remove(devDesc);
128 return INVALID_OPERATION;
129 }
Paul McLeane743a472015-01-28 11:07:31 -0800130 mAvailableOutputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700131 } else {
132 return NO_MEMORY;
Eric Laurente552edb2014-03-10 17:42:56 -0700133 }
134
François Gaffie44481e72016-04-20 07:49:57 +0200135 // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
136 // parameters on newly connected devices (instead of opening the outputs...)
137 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
138
Eric Laurenta1d525f2015-01-29 13:36:45 -0800139 if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700140 mAvailableOutputDevices.remove(devDesc);
François Gaffie44481e72016-04-20 07:49:57 +0200141
142 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
143 devDesc->mAddress);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700144 return INVALID_OPERATION;
145 }
François Gaffie2110e042015-03-24 08:41:51 +0100146 // Propagate device availability to Engine
147 mEngine->setDeviceConnectionState(devDesc, state);
148
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700149 // outputs should never be empty here
150 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
151 "checkOutputsForDevice() returned no outputs but status OK");
152 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
153 outputs.size());
Eric Laurent3ae5f312015-02-03 17:12:08 -0800154
Eric Laurent3ae5f312015-02-03 17:12:08 -0800155 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700156 // handle output device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700157 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700158 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700159 ALOGW("setDeviceConnectionState() device not connected: %x", device);
160 return INVALID_OPERATION;
161 }
162
Paul McLean5c477aa2014-08-20 16:47:57 -0700163 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
164
Paul McLeane743a472015-01-28 11:07:31 -0800165 // Send Disconnect to HALs
François Gaffie44481e72016-04-20 07:49:57 +0200166 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700167
Eric Laurente552edb2014-03-10 17:42:56 -0700168 // remove device from available output devices
Eric Laurent3a4311c2014-03-17 12:00:47 -0700169 mAvailableOutputDevices.remove(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700170
Eric Laurenta1d525f2015-01-29 13:36:45 -0800171 checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
François Gaffie2110e042015-03-24 08:41:51 +0100172
173 // Propagate device availability to Engine
174 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurente552edb2014-03-10 17:42:56 -0700175 } break;
176
177 default:
178 ALOGE("setDeviceConnectionState() invalid state: %x", state);
179 return BAD_VALUE;
180 }
181
Eric Laurent3a4311c2014-03-17 12:00:47 -0700182 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
183 // output is suspended before any tracks are moved to it
Eric Laurente552edb2014-03-10 17:42:56 -0700184 checkA2dpSuspend();
185 checkOutputForAllStrategies();
186 // outputs must be closed after checkOutputForAllStrategies() is executed
187 if (!outputs.isEmpty()) {
188 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700189 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -0700190 // close unused outputs after device disconnection or direct outputs that have been
191 // opened by checkOutputsForDevice() to query dynamic parameters
Eric Laurent3b73df72014-03-11 09:06:29 -0700192 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Eric Laurente552edb2014-03-10 17:42:56 -0700193 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
194 (desc->mDirectOpenCount == 0))) {
195 closeOutput(outputs[i]);
196 }
197 }
Eric Laurent3a4311c2014-03-17 12:00:47 -0700198 // check again after closing A2DP output to reset mA2dpSuspended if needed
199 checkA2dpSuspend();
Eric Laurente552edb2014-03-10 17:42:56 -0700200 }
201
202 updateDevicesAndOutputs();
Eric Laurent87ffa392015-05-22 10:32:38 -0700203 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700204 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
205 updateCallRouting(newDevice);
206 }
Eric Laurente552edb2014-03-10 17:42:56 -0700207 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700208 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
209 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
210 audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700211 // do not force device change on duplicated output because if device is 0, it will
212 // also force a device 0 for the two outputs it is duplicated to which may override
213 // a valid device selection on those outputs.
Eric Laurentc75307b2015-03-17 15:29:32 -0700214 bool force = !desc->isDuplicated()
François Gaffie53615e22015-03-19 09:24:12 +0100215 && (!device_distinguishes_on_address(device)
Eric Laurentc2730ba2014-07-20 15:47:07 -0700216 // always force when disconnecting (a non-duplicated device)
217 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
Eric Laurentc75307b2015-03-17 15:29:32 -0700218 setOutputDevice(desc, newDevice, force, 0);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700219 }
Eric Laurente552edb2014-03-10 17:42:56 -0700220 }
221
Eric Laurentd60560a2015-04-10 11:31:20 -0700222 if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
223 cleanUpForDevice(devDesc);
224 }
225
Eric Laurent72aa32f2014-05-30 18:51:48 -0700226 mpClientInterface->onAudioPortListUpdate();
Eric Laurentb71e58b2014-05-29 16:08:11 -0700227 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700228 } // end if is output device
229
Eric Laurente552edb2014-03-10 17:42:56 -0700230 // handle input devices
231 if (audio_is_input_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700232 SortedVector <audio_io_handle_t> inputs;
233
Eric Laurent3a4311c2014-03-17 12:00:47 -0700234 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700235 switch (state)
236 {
237 // handle input device connection
Eric Laurent3b73df72014-03-11 09:06:29 -0700238 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700239 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700240 ALOGW("setDeviceConnectionState() device already connected: %d", device);
241 return INVALID_OPERATION;
242 }
François Gaffie53615e22015-03-19 09:24:12 +0100243 sp<HwModule> module = mHwModules.getModuleForDevice(device);
Eric Laurent6a94d692014-05-20 11:18:06 -0700244 if (module == NULL) {
245 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
246 device);
247 return INVALID_OPERATION;
248 }
François Gaffie44481e72016-04-20 07:49:57 +0200249
250 // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
251 // parameters on newly connected devices (instead of opening the inputs...)
252 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
253
Paul McLean9080a4c2015-06-18 08:24:02 -0700254 if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
François Gaffie44481e72016-04-20 07:49:57 +0200255 broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
256 devDesc->mAddress);
Eric Laurentd4692962014-05-05 18:13:44 -0700257 return INVALID_OPERATION;
258 }
259
Eric Laurent3a4311c2014-03-17 12:00:47 -0700260 index = mAvailableInputDevices.add(devDesc);
261 if (index >= 0) {
Paul McLeane743a472015-01-28 11:07:31 -0800262 mAvailableInputDevices[index]->attach(module);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700263 } else {
264 return NO_MEMORY;
265 }
Eric Laurent3ae5f312015-02-03 17:12:08 -0800266
François Gaffie2110e042015-03-24 08:41:51 +0100267 // Propagate device availability to Engine
268 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700269 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700270
271 // handle input device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700272 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700273 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700274 ALOGW("setDeviceConnectionState() device not connected: %d", device);
275 return INVALID_OPERATION;
276 }
Paul McLean5c477aa2014-08-20 16:47:57 -0700277
278 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
279
280 // Set Disconnect to HALs
François Gaffie44481e72016-04-20 07:49:57 +0200281 broadcastDeviceConnectionState(device, state, devDesc->mAddress);
Paul McLean5c477aa2014-08-20 16:47:57 -0700282
Paul McLean9080a4c2015-06-18 08:24:02 -0700283 checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700284 mAvailableInputDevices.remove(devDesc);
Paul McLean5c477aa2014-08-20 16:47:57 -0700285
François Gaffie2110e042015-03-24 08:41:51 +0100286 // Propagate device availability to Engine
287 mEngine->setDeviceConnectionState(devDesc, state);
Eric Laurentd4692962014-05-05 18:13:44 -0700288 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700289
290 default:
291 ALOGE("setDeviceConnectionState() invalid state: %x", state);
292 return BAD_VALUE;
293 }
294
Eric Laurentd4692962014-05-05 18:13:44 -0700295 closeAllInputs();
Eric Laurent5f5fca52016-08-04 11:48:57 -0700296 // As the input device list can impact the output device selection, update
297 // getDeviceForStrategy() cache
298 updateDevicesAndOutputs();
Eric Laurente552edb2014-03-10 17:42:56 -0700299
Eric Laurent87ffa392015-05-22 10:32:38 -0700300 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700301 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
302 updateCallRouting(newDevice);
303 }
304
Eric Laurentd60560a2015-04-10 11:31:20 -0700305 if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
306 cleanUpForDevice(devDesc);
307 }
308
Eric Laurentb52c1522014-05-20 11:27:36 -0700309 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700310 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700311 } // end if is input device
Eric Laurente552edb2014-03-10 17:42:56 -0700312
313 ALOGW("setDeviceConnectionState() invalid device: %x", device);
314 return BAD_VALUE;
315}
316
Eric Laurente0720872014-03-11 09:30:41 -0700317audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
François Gaffie53615e22015-03-19 09:24:12 +0100318 const char *device_address)
Eric Laurente552edb2014-03-10 17:42:56 -0700319{
Eric Laurent634b7142016-04-20 13:48:02 -0700320 sp<DeviceDescriptor> devDesc =
321 mHwModules.getDeviceDescriptor(device, device_address, "",
322 (strlen(device_address) != 0)/*matchAddress*/);
323
324 if (devDesc == 0) {
325 ALOGW("getDeviceConnectionState() undeclared device, type %08x, address: %s",
326 device, device_address);
327 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
328 }
François Gaffie53615e22015-03-19 09:24:12 +0100329
Eric Laurent3a4311c2014-03-17 12:00:47 -0700330 DeviceVector *deviceVector;
331
Eric Laurente552edb2014-03-10 17:42:56 -0700332 if (audio_is_output_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700333 deviceVector = &mAvailableOutputDevices;
Eric Laurente552edb2014-03-10 17:42:56 -0700334 } else if (audio_is_input_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700335 deviceVector = &mAvailableInputDevices;
336 } else {
337 ALOGW("getDeviceConnectionState() invalid device type %08x", device);
338 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurente552edb2014-03-10 17:42:56 -0700339 }
Eric Laurent634b7142016-04-20 13:48:02 -0700340
341 return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
342 AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurenta1d525f2015-01-29 13:36:45 -0800343}
344
Pavlin Radoslavovf862bc62016-12-26 18:57:22 -0800345status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
346 const char *device_address,
347 const char *device_name)
348{
349 status_t status;
350
351 ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
352 device, device_address, device_name);
353
Pavlin Radoslavovc694ff42017-01-09 23:27:29 -0800354 // connect/disconnect only 1 device at a time
355 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
356
Pavlin Radoslavovf862bc62016-12-26 18:57:22 -0800357 // Check if the device is currently connected
358 sp<DeviceDescriptor> devDesc =
359 mHwModules.getDeviceDescriptor(device, device_address, device_name);
360 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
361 if (index < 0) {
362 // Nothing to do: device is not connected
363 return NO_ERROR;
364 }
365
366 // Toggle the device state: UNAVAILABLE -> AVAILABLE
367 // This will force reading again the device configuration
368 status = setDeviceConnectionState(device,
369 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
370 device_address, device_name);
371 if (status != NO_ERROR) {
372 ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
373 status);
374 return status;
375 }
376
377 status = setDeviceConnectionState(device,
378 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
379 device_address, device_name);
380 if (status != NO_ERROR) {
381 ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
382 status);
383 return status;
384 }
385
386 return NO_ERROR;
387}
388
Eric Laurentdc462862016-07-19 12:29:53 -0700389uint32_t AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs)
Eric Laurentc2730ba2014-07-20 15:47:07 -0700390{
391 bool createTxPatch = false;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700392 status_t status;
393 audio_patch_handle_t afPatchHandle;
394 DeviceVector deviceList;
Eric Laurentdc462862016-07-19 12:29:53 -0700395 uint32_t muteWaitMs = 0;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700396
Andy Hunga76c7de2016-12-13 19:14:31 -0800397 if(!hasPrimaryOutput() || mPrimaryOutput->device() == AUDIO_DEVICE_OUT_STUB) {
Eric Laurentdc462862016-07-19 12:29:53 -0700398 return muteWaitMs;
Eric Laurent87ffa392015-05-22 10:32:38 -0700399 }
Eric Laurentc73ca6e2014-12-12 14:34:22 -0800400 audio_devices_t txDevice = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700401 ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
402
403 // release existing RX patch if any
404 if (mCallRxPatch != 0) {
405 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
406 mCallRxPatch.clear();
407 }
408 // release TX patch if any
409 if (mCallTxPatch != 0) {
410 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
411 mCallTxPatch.clear();
412 }
413
414 // If the RX device is on the primary HW module, then use legacy routing method for voice calls
415 // via setOutputDevice() on primary output.
416 // Otherwise, create two audio patches for TX and RX path.
417 if (availablePrimaryOutputDevices() & rxDevice) {
Eric Laurentdc462862016-07-19 12:29:53 -0700418 muteWaitMs = setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700419 // If the TX device is also on the primary HW module, setOutputDevice() will take care
420 // of it due to legacy implementation. If not, create a patch.
421 if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
422 == AUDIO_DEVICE_NONE) {
423 createTxPatch = true;
424 }
Eric Laurent8ae73122016-04-12 10:13:29 -0700425 } else { // create RX path audio patch
426 struct audio_patch patch;
427
428 patch.num_sources = 1;
429 patch.num_sinks = 1;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700430 deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
431 ALOG_ASSERT(!deviceList.isEmpty(),
432 "updateCallRouting() selected device not in output device list");
433 sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
434 deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
435 ALOG_ASSERT(!deviceList.isEmpty(),
436 "updateCallRouting() no telephony RX device");
437 sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
438
439 rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
440 rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
441
442 // request to reuse existing output stream if one is already opened to reach the RX device
443 SortedVector<audio_io_handle_t> outputs =
444 getOutputsForDevice(rxDevice, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700445 audio_io_handle_t output = selectOutput(outputs,
446 AUDIO_OUTPUT_FLAG_NONE,
447 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700448 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700449 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700450 ALOG_ASSERT(!outputDesc->isDuplicated(),
451 "updateCallRouting() RX device output is duplicated");
452 outputDesc->toAudioPortConfig(&patch.sources[1]);
Eric Laurent3bcf8592015-04-03 12:13:24 -0700453 patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700454 patch.num_sources = 2;
455 }
456
457 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
Eric Laurentdc462862016-07-19 12:29:53 -0700458 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700459 ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
460 status);
461 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100462 mCallRxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700463 mCallRxPatch->mAfPatchHandle = afPatchHandle;
464 mCallRxPatch->mUid = mUidCached;
465 }
466 createTxPatch = true;
467 }
Eric Laurent8ae73122016-04-12 10:13:29 -0700468 if (createTxPatch) { // create TX path audio patch
Eric Laurentc2730ba2014-07-20 15:47:07 -0700469 struct audio_patch patch;
Eric Laurent8ae73122016-04-12 10:13:29 -0700470
Eric Laurentc2730ba2014-07-20 15:47:07 -0700471 patch.num_sources = 1;
472 patch.num_sinks = 1;
473 deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
474 ALOG_ASSERT(!deviceList.isEmpty(),
475 "updateCallRouting() selected device not in input device list");
476 sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
477 txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
478 deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
479 ALOG_ASSERT(!deviceList.isEmpty(),
480 "updateCallRouting() no telephony TX device");
481 sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
482 txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
483
484 SortedVector<audio_io_handle_t> outputs =
485 getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
Eric Laurent8838a382014-09-08 16:44:28 -0700486 audio_io_handle_t output = selectOutput(outputs,
487 AUDIO_OUTPUT_FLAG_NONE,
488 AUDIO_FORMAT_INVALID);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700489 // request to reuse existing output stream if one is already opened to reach the TX
490 // path output device
491 if (output != AUDIO_IO_HANDLE_NONE) {
492 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
493 ALOG_ASSERT(!outputDesc->isDuplicated(),
494 "updateCallRouting() RX device output is duplicated");
495 outputDesc->toAudioPortConfig(&patch.sources[1]);
Eric Laurent3bcf8592015-04-03 12:13:24 -0700496 patch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700497 patch.num_sources = 2;
498 }
499
Eric Laurentc0a889f2015-10-14 14:36:34 -0700500 // terminate active capture if on the same HW module as the call TX source device
501 // FIXME: would be better to refine to only inputs whose profile connects to the
502 // call TX device but this information is not in the audio patch and logic here must be
503 // symmetric to the one in startInput()
Eric Laurentfb66dd92016-01-28 18:32:03 -0800504 Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
505 for (size_t i = 0; i < activeInputs.size(); i++) {
506 sp<AudioInputDescriptor> activeDesc = activeInputs[i];
507 if (activeDesc->hasSameHwModuleAs(txSourceDeviceDesc)) {
508 AudioSessionCollection activeSessions =
509 activeDesc->getAudioSessions(true /*activeOnly*/);
510 for (size_t j = 0; j < activeSessions.size(); j++) {
511 audio_session_t activeSession = activeSessions.keyAt(j);
512 stopInput(activeDesc->mIoHandle, activeSession);
513 releaseInput(activeDesc->mIoHandle, activeSession);
514 }
Eric Laurentc0a889f2015-10-14 14:36:34 -0700515 }
516 }
517
Eric Laurentc2730ba2014-07-20 15:47:07 -0700518 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
Eric Laurentdc462862016-07-19 12:29:53 -0700519 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, delayMs);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700520 ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
521 status);
522 if (status == NO_ERROR) {
François Gaffie98cc1912015-03-18 17:52:40 +0100523 mCallTxPatch = new AudioPatch(&patch, mUidCached);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700524 mCallTxPatch->mAfPatchHandle = afPatchHandle;
525 mCallTxPatch->mUid = mUidCached;
526 }
527 }
Eric Laurentdc462862016-07-19 12:29:53 -0700528
529 return muteWaitMs;
Eric Laurentc2730ba2014-07-20 15:47:07 -0700530}
531
Eric Laurente0720872014-03-11 09:30:41 -0700532void AudioPolicyManager::setPhoneState(audio_mode_t state)
Eric Laurente552edb2014-03-10 17:42:56 -0700533{
534 ALOGV("setPhoneState() state %d", state);
François Gaffie2110e042015-03-24 08:41:51 +0100535 // store previous phone state for management of sonification strategy below
536 int oldState = mEngine->getPhoneState();
537
538 if (mEngine->setPhoneState(state) != NO_ERROR) {
539 ALOGW("setPhoneState() invalid or same state %d", state);
Eric Laurente552edb2014-03-10 17:42:56 -0700540 return;
541 }
François Gaffie2110e042015-03-24 08:41:51 +0100542 /// Opens: can these line be executed after the switch of volume curves???
Eric Laurente552edb2014-03-10 17:42:56 -0700543 // if leaving call state, handle special case of active streams
544 // pertaining to sonification strategy see handleIncallSonification()
Eric Laurent63dea1d2015-07-02 17:10:28 -0700545 if (isStateInCall(oldState)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700546 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent794fde22016-03-11 09:50:45 -0800547 for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700548 handleIncallSonification((audio_stream_type_t)stream, false, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700549 }
Eric Laurent2cbe89a2014-12-19 11:49:08 -0800550
Eric Laurent63dea1d2015-07-02 17:10:28 -0700551 // force reevaluating accessibility routing when call stops
Eric Laurent2cbe89a2014-12-19 11:49:08 -0800552 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -0700553 }
554
François Gaffie2110e042015-03-24 08:41:51 +0100555 /**
556 * Switching to or from incall state or switching between telephony and VoIP lead to force
557 * routing command.
558 */
559 bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
560 || (is_state_in_call(state) && (state != oldState)));
Eric Laurente552edb2014-03-10 17:42:56 -0700561
562 // check for device and output changes triggered by new phone state
Eric Laurente552edb2014-03-10 17:42:56 -0700563 checkA2dpSuspend();
564 checkOutputForAllStrategies();
565 updateDevicesAndOutputs();
566
Eric Laurente552edb2014-03-10 17:42:56 -0700567 int delayMs = 0;
568 if (isStateInCall(state)) {
569 nsecs_t sysTime = systemTime();
570 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700571 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700572 // mute media and sonification strategies and delay device switch by the largest
573 // latency of any output where either strategy is active.
574 // This avoid sending the ring tone or music tail into the earpiece or headset.
François Gaffiead3183e2015-03-18 16:55:35 +0100575 if ((isStrategyActive(desc, STRATEGY_MEDIA,
576 SONIFICATION_HEADSET_MUSIC_DELAY,
577 sysTime) ||
578 isStrategyActive(desc, STRATEGY_SONIFICATION,
579 SONIFICATION_HEADSET_MUSIC_DELAY,
580 sysTime)) &&
Eric Laurentc75307b2015-03-17 15:29:32 -0700581 (delayMs < (int)desc->latency()*2)) {
582 delayMs = desc->latency()*2;
Eric Laurente552edb2014-03-10 17:42:56 -0700583 }
Eric Laurentc75307b2015-03-17 15:29:32 -0700584 setStrategyMute(STRATEGY_MEDIA, true, desc);
585 setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
Eric Laurente552edb2014-03-10 17:42:56 -0700586 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
Eric Laurentc75307b2015-03-17 15:29:32 -0700587 setStrategyMute(STRATEGY_SONIFICATION, true, desc);
588 setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
Eric Laurente552edb2014-03-10 17:42:56 -0700589 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
590 }
591 }
592
Eric Laurent87ffa392015-05-22 10:32:38 -0700593 if (hasPrimaryOutput()) {
594 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
595 // the device returned is not necessarily reachable via this output
596 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
597 // force routing command to audio hardware when ending call
598 // even if no device change is needed
599 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
600 rxDevice = mPrimaryOutput->device();
601 }
Eric Laurente552edb2014-03-10 17:42:56 -0700602
Eric Laurent87ffa392015-05-22 10:32:38 -0700603 if (state == AUDIO_MODE_IN_CALL) {
604 updateCallRouting(rxDevice, delayMs);
605 } else if (oldState == AUDIO_MODE_IN_CALL) {
606 if (mCallRxPatch != 0) {
607 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
608 mCallRxPatch.clear();
609 }
610 if (mCallTxPatch != 0) {
611 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
612 mCallTxPatch.clear();
613 }
614 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
615 } else {
616 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700617 }
Eric Laurentc2730ba2014-07-20 15:47:07 -0700618 }
Eric Laurente552edb2014-03-10 17:42:56 -0700619 // if entering in call state, handle special case of active streams
620 // pertaining to sonification strategy see handleIncallSonification()
621 if (isStateInCall(state)) {
622 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent794fde22016-03-11 09:50:45 -0800623 for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700624 handleIncallSonification((audio_stream_type_t)stream, true, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700625 }
Eric Laurent63dea1d2015-07-02 17:10:28 -0700626
627 // force reevaluating accessibility routing when call starts
628 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -0700629 }
630
631 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
Eric Laurent3b73df72014-03-11 09:06:29 -0700632 if (state == AUDIO_MODE_RINGTONE &&
633 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700634 mLimitRingtoneVolume = true;
635 } else {
636 mLimitRingtoneVolume = false;
637 }
638}
639
Jean-Michel Trivi887a9ed2015-03-31 18:02:24 -0700640audio_mode_t AudioPolicyManager::getPhoneState() {
641 return mEngine->getPhoneState();
642}
643
Eric Laurente0720872014-03-11 09:30:41 -0700644void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
Eric Laurent3b73df72014-03-11 09:06:29 -0700645 audio_policy_forced_cfg_t config)
Eric Laurente552edb2014-03-10 17:42:56 -0700646{
François Gaffie2110e042015-03-24 08:41:51 +0100647 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
Eric Laurent8dc87a62017-05-16 19:00:40 -0700648 if (config == mEngine->getForceUse(usage)) {
649 return;
650 }
Eric Laurente552edb2014-03-10 17:42:56 -0700651
François Gaffie2110e042015-03-24 08:41:51 +0100652 if (mEngine->setForceUse(usage, config) != NO_ERROR) {
653 ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
654 return;
Eric Laurente552edb2014-03-10 17:42:56 -0700655 }
François Gaffie2110e042015-03-24 08:41:51 +0100656 bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
657 (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
658 (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
Eric Laurente552edb2014-03-10 17:42:56 -0700659
660 // check for device and output changes triggered by new force usage
661 checkA2dpSuspend();
662 checkOutputForAllStrategies();
663 updateDevicesAndOutputs();
Phil Burk09bc4612016-02-24 15:58:15 -0800664
Eric Laurentdc462862016-07-19 12:29:53 -0700665 //FIXME: workaround for truncated touch sounds
666 // to be removed when the problem is handled by system UI
667 uint32_t delayMs = 0;
668 uint32_t waitMs = 0;
669 if (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) {
670 delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
671 }
Eric Laurent87ffa392015-05-22 10:32:38 -0700672 if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700673 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
Eric Laurentdc462862016-07-19 12:29:53 -0700674 waitMs = updateCallRouting(newDevice, delayMs);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700675 }
Eric Laurente552edb2014-03-10 17:42:56 -0700676 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700677 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
678 audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
679 if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
Eric Laurentdc462862016-07-19 12:29:53 -0700680 waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
681 delayMs);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700682 }
Eric Laurente552edb2014-03-10 17:42:56 -0700683 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
Eric Laurentdc462862016-07-19 12:29:53 -0700684 applyStreamVolumes(outputDesc, newDevice, waitMs, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700685 }
686 }
687
Eric Laurentfb66dd92016-01-28 18:32:03 -0800688 Vector<sp <AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
689 for (size_t i = 0; i < activeInputs.size(); i++) {
690 sp<AudioInputDescriptor> activeDesc = activeInputs[i];
691 audio_devices_t newDevice = getNewInputDevice(activeDesc);
Eric Laurentc171c7c2015-09-25 12:21:06 -0700692 // Force new input selection if the new device can not be reached via current input
Eric Laurentfb66dd92016-01-28 18:32:03 -0800693 if (activeDesc->mProfile->getSupportedDevices().types() &
694 (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
695 setInputDevice(activeDesc->mIoHandle, newDevice);
Eric Laurentc171c7c2015-09-25 12:21:06 -0700696 } else {
Eric Laurentfb66dd92016-01-28 18:32:03 -0800697 closeInput(activeDesc->mIoHandle);
Eric Laurentc171c7c2015-09-25 12:21:06 -0700698 }
Eric Laurente552edb2014-03-10 17:42:56 -0700699 }
Eric Laurente552edb2014-03-10 17:42:56 -0700700}
701
Eric Laurente0720872014-03-11 09:30:41 -0700702void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
Eric Laurente552edb2014-03-10 17:42:56 -0700703{
704 ALOGV("setSystemProperty() property %s, value %s", property, value);
705}
706
707// Find a direct output profile compatible with the parameters passed, even if the input flags do
708// not explicitly request a direct output
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -0800709sp<IOProfile> AudioPolicyManager::getProfileForDirectOutput(
Eric Laurente552edb2014-03-10 17:42:56 -0700710 audio_devices_t device,
711 uint32_t samplingRate,
712 audio_format_t format,
713 audio_channel_mask_t channelMask,
714 audio_output_flags_t flags)
715{
Eric Laurent861a6282015-05-18 15:40:16 -0700716 // only retain flags that will drive the direct output profile selection
717 // if explicitly requested
718 static const uint32_t kRelevantFlags =
Haynes Mathew George84c621e2017-04-25 11:41:50 -0700719 (AUDIO_OUTPUT_FLAG_HW_AV_SYNC | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD |
720 AUDIO_OUTPUT_FLAG_VOIP_RX);
Eric Laurent861a6282015-05-18 15:40:16 -0700721 flags =
722 (audio_output_flags_t)((flags & kRelevantFlags) | AUDIO_OUTPUT_FLAG_DIRECT);
723
724 sp<IOProfile> profile;
725
Eric Laurente552edb2014-03-10 17:42:56 -0700726 for (size_t i = 0; i < mHwModules.size(); i++) {
727 if (mHwModules[i]->mHandle == 0) {
728 continue;
729 }
730 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
Eric Laurent861a6282015-05-18 15:40:16 -0700731 sp<IOProfile> curProfile = mHwModules[i]->mOutputProfiles[j];
732 if (!curProfile->isCompatibleProfile(device, String8(""),
Andy Hungf129b032015-04-07 13:45:50 -0700733 samplingRate, NULL /*updatedSamplingRate*/,
734 format, NULL /*updatedFormat*/,
735 channelMask, NULL /*updatedChannelMask*/,
Eric Laurent861a6282015-05-18 15:40:16 -0700736 flags)) {
737 continue;
738 }
739 // reject profiles not corresponding to a device currently available
François Gaffiea8ecc2c2015-11-09 16:10:40 +0100740 if ((mAvailableOutputDevices.types() & curProfile->getSupportedDevicesType()) == 0) {
Eric Laurent861a6282015-05-18 15:40:16 -0700741 continue;
742 }
743 // if several profiles are compatible, give priority to one with offload capability
François Gaffiea8ecc2c2015-11-09 16:10:40 +0100744 if (profile != 0 && ((curProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0)) {
Eric Laurent861a6282015-05-18 15:40:16 -0700745 continue;
746 }
747 profile = curProfile;
François Gaffiea8ecc2c2015-11-09 16:10:40 +0100748 if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
Eric Laurent861a6282015-05-18 15:40:16 -0700749 break;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700750 }
Eric Laurente552edb2014-03-10 17:42:56 -0700751 }
752 }
Eric Laurent861a6282015-05-18 15:40:16 -0700753 return profile;
Eric Laurente552edb2014-03-10 17:42:56 -0700754}
755
Eric Laurente0720872014-03-11 09:30:41 -0700756audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +0100757 uint32_t samplingRate,
758 audio_format_t format,
759 audio_channel_mask_t channelMask,
760 audio_output_flags_t flags,
761 const audio_offload_info_t *offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -0700762{
Eric Laurent3b73df72014-03-11 09:06:29 -0700763 routing_strategy strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -0700764 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
765 ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
766 device, stream, samplingRate, format, channelMask, flags);
767
Kevin Rocard169753c2017-03-06 14:18:23 -0800768 return getOutputForDevice(device, AUDIO_SESSION_ALLOCATE, stream, samplingRate, format,
769 channelMask, flags, offloadInfo);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700770}
771
Eric Laurente83b55d2014-11-14 10:06:21 -0800772status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
773 audio_io_handle_t *output,
774 audio_session_t session,
775 audio_stream_type_t *stream,
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700776 uid_t uid,
Eric Laurent20b9ef02016-12-05 11:03:16 -0800777 const audio_config_t *config,
Eric Laurente83b55d2014-11-14 10:06:21 -0800778 audio_output_flags_t flags,
Eric Laurent2ac76942017-06-22 17:17:09 -0700779 audio_port_handle_t *selectedDeviceId,
Eric Laurent20b9ef02016-12-05 11:03:16 -0800780 audio_port_handle_t *portId)
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700781{
Eric Laurente83b55d2014-11-14 10:06:21 -0800782 audio_attributes_t attributes;
783 if (attr != NULL) {
784 if (!isValidAttributes(attr)) {
785 ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
786 attr->usage, attr->content_type, attr->flags,
787 attr->tags);
788 return BAD_VALUE;
789 }
790 attributes = *attr;
791 } else {
792 if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
793 ALOGE("getOutputForAttr(): invalid stream type");
794 return BAD_VALUE;
795 }
796 stream_type_to_audio_attributes(*stream, &attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700797 }
Eric Laurent20b9ef02016-12-05 11:03:16 -0800798
799 // TODO: check for existing client for this port ID
800 if (*portId == AUDIO_PORT_HANDLE_NONE) {
801 *portId = AudioPort::getNextUniqueId();
802 }
803
Eric Laurentc75307b2015-03-17 15:29:32 -0700804 sp<SwAudioOutputDescriptor> desc;
Jean-Michel Trivie8deced2016-02-11 12:50:39 -0800805 if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
François Gaffie036e1e92015-03-19 10:16:24 +0100806 ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
Eric Laurent20b9ef02016-12-05 11:03:16 -0800807 if (!audio_has_proportional_frames(config->format)) {
François Gaffie036e1e92015-03-19 10:16:24 +0100808 return BAD_VALUE;
Eric Laurent275e8e92014-11-30 15:14:47 -0800809 }
François Gaffie036e1e92015-03-19 10:16:24 +0100810 *stream = streamTypefromAttributesInt(&attributes);
811 *output = desc->mIoHandle;
812 ALOGV("getOutputForAttr() returns output %d", *output);
813 return NO_ERROR;
Eric Laurent275e8e92014-11-30 15:14:47 -0800814 }
815 if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
816 ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
817 return BAD_VALUE;
818 }
819
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700820 ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
821 " session %d selectedDeviceId %d",
822 attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
Eric Laurent2ac76942017-06-22 17:17:09 -0700823 session, *selectedDeviceId);
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700824
825 *stream = streamTypefromAttributesInt(&attributes);
826
827 // Explicit routing?
828 sp<DeviceDescriptor> deviceDesc;
Eric Laurent2ac76942017-06-22 17:17:09 -0700829 if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
830 for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
831 if (mAvailableOutputDevices[i]->getId() == *selectedDeviceId) {
832 deviceDesc = mAvailableOutputDevices[i];
833 break;
834 }
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700835 }
836 }
837 mOutputRoutes.addRoute(session, *stream, SessionRoute::SOURCE_TYPE_NA, deviceDesc, uid);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700838
Eric Laurente83b55d2014-11-14 10:06:21 -0800839 routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700840 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
Eric Laurent93c3d412014-08-01 14:48:35 -0700841
Eric Laurente83b55d2014-11-14 10:06:21 -0800842 if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
Eric Laurent93c3d412014-08-01 14:48:35 -0700843 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
844 }
845
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -0700846 ALOGV("getOutputForAttr() device 0x%x, samplingRate %d, format %x, channelMask %x, flags %x",
Eric Laurent20b9ef02016-12-05 11:03:16 -0800847 device, config->sample_rate, config->format, config->channel_mask, flags);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700848
Kevin Rocard169753c2017-03-06 14:18:23 -0800849 *output = getOutputForDevice(device, session, *stream,
Eric Laurent20b9ef02016-12-05 11:03:16 -0800850 config->sample_rate, config->format, config->channel_mask,
851 flags, &config->offload_info);
Eric Laurente83b55d2014-11-14 10:06:21 -0800852 if (*output == AUDIO_IO_HANDLE_NONE) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -0700853 mOutputRoutes.removeRoute(session);
Eric Laurente83b55d2014-11-14 10:06:21 -0800854 return INVALID_OPERATION;
855 }
Paul McLeanaa981192015-03-21 09:55:15 -0700856
Eric Laurent2ac76942017-06-22 17:17:09 -0700857 DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
858 *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
859 : AUDIO_PORT_HANDLE_NONE;
860
861 ALOGV(" getOutputForAttr() returns output %d selectedDeviceId %d", *output, *selectedDeviceId);
862
Eric Laurente83b55d2014-11-14 10:06:21 -0800863 return NO_ERROR;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700864}
865
866audio_io_handle_t AudioPolicyManager::getOutputForDevice(
867 audio_devices_t device,
Kevin Rocard169753c2017-03-06 14:18:23 -0800868 audio_session_t session,
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700869 audio_stream_type_t stream,
870 uint32_t samplingRate,
871 audio_format_t format,
872 audio_channel_mask_t channelMask,
873 audio_output_flags_t flags,
874 const audio_offload_info_t *offloadInfo)
875{
Eric Laurentcf2c0212014-07-25 16:20:43 -0700876 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700877 status_t status;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700878
Eric Laurente552edb2014-03-10 17:42:56 -0700879#ifdef AUDIO_POLICY_TEST
880 if (mCurOutput != 0) {
881 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
882 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
883
884 if (mTestOutputs[mCurOutput] == 0) {
885 ALOGV("getOutput() opening test output");
Eric Laurentc75307b2015-03-17 15:29:32 -0700886 sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
887 mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -0700888 outputDesc->mDevice = mTestDevice;
Eric Laurente552edb2014-03-10 17:42:56 -0700889 outputDesc->mLatency = mTestLatencyMs;
Eric Laurent3b73df72014-03-11 09:06:29 -0700890 outputDesc->mFlags =
891 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
Eric Laurente552edb2014-03-10 17:42:56 -0700892 outputDesc->mRefCount[stream] = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700893 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
894 config.sample_rate = mTestSamplingRate;
895 config.channel_mask = mTestChannels;
896 config.format = mTestFormat;
Phil Burk77cce802014-08-04 16:18:15 -0700897 if (offloadInfo != NULL) {
898 config.offload_info = *offloadInfo;
899 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700900 status = mpClientInterface->openOutput(0,
901 &mTestOutputs[mCurOutput],
902 &config,
903 &outputDesc->mDevice,
904 String8(""),
905 &outputDesc->mLatency,
906 outputDesc->mFlags);
907 if (status == NO_ERROR) {
908 outputDesc->mSamplingRate = config.sample_rate;
909 outputDesc->mFormat = config.format;
910 outputDesc->mChannelMask = config.channel_mask;
Eric Laurente552edb2014-03-10 17:42:56 -0700911 AudioParameter outputCmd = AudioParameter();
912 outputCmd.addInt(String8("set_id"),mCurOutput);
913 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
914 addOutput(mTestOutputs[mCurOutput], outputDesc);
915 }
916 }
917 return mTestOutputs[mCurOutput];
918 }
919#endif //AUDIO_POLICY_TEST
920
921 // open a direct output if required by specified parameters
922 //force direct flag if offload flag is set: offloading implies a direct output stream
923 // and all common behaviors are driven by checking only the direct flag
924 // this should normally be set appropriately in the policy configuration file
925 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700926 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurente552edb2014-03-10 17:42:56 -0700927 }
Eric Laurent93c3d412014-08-01 14:48:35 -0700928 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
929 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
930 }
Eric Laurente83b55d2014-11-14 10:06:21 -0800931 // only allow deep buffering for music stream type
932 if (stream != AUDIO_STREAM_MUSIC) {
933 flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
Ravi Kumar Alamanda439e4ed2015-04-03 12:13:21 -0700934 } else if (/* stream == AUDIO_STREAM_MUSIC && */
935 flags == AUDIO_OUTPUT_FLAG_NONE &&
936 property_get_bool("audio.deep_buffer.media", false /* default_value */)) {
937 // use DEEP_BUFFER as default output for music stream type
938 flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
Eric Laurente83b55d2014-11-14 10:06:21 -0800939 }
Ravi Kumar Alamandac36a8892015-04-24 16:35:49 -0700940 if (stream == AUDIO_STREAM_TTS) {
941 flags = AUDIO_OUTPUT_FLAG_TTS;
Haynes Mathew George84c621e2017-04-25 11:41:50 -0700942 } else if (stream == AUDIO_STREAM_VOICE_CALL &&
Haynes Mathew George84c621e2017-04-25 11:41:50 -0700943 audio_is_linear_pcm(format)) {
944 flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
945 AUDIO_OUTPUT_FLAG_DIRECT);
946 ALOGV("Set VoIP and Direct output flags for PCM format");
Ravi Kumar Alamandac36a8892015-04-24 16:35:49 -0700947 }
Eric Laurente552edb2014-03-10 17:42:56 -0700948
Eric Laurentb732cf52014-09-24 19:08:21 -0700949 sp<IOProfile> profile;
950
951 // skip direct output selection if the request can obviously be attached to a mixed output
Eric Laurentc2607842014-09-29 09:43:03 -0700952 // and not explicitly requested
953 if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
Glenn Kasten05ddca52016-02-11 08:17:12 -0800954 audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX &&
Eric Laurentb732cf52014-09-24 19:08:21 -0700955 audio_channel_count_from_out_mask(channelMask) <= 2) {
956 goto non_direct_output;
957 }
958
Andy Hung2ddee192015-12-18 17:34:44 -0800959 // Do not allow offloading if one non offloadable effect is enabled or MasterMono is enabled.
960 // This prevents creating an offloaded track and tearing it down immediately after start
961 // when audioflinger detects there is an active non offloadable effect.
Eric Laurente552edb2014-03-10 17:42:56 -0700962 // FIXME: We should check the audio session here but we do not have it in this context.
963 // This may prevent offloading in rare situations where effects are left active by apps
964 // in the background.
Eric Laurentb732cf52014-09-24 19:08:21 -0700965
Eric Laurente552edb2014-03-10 17:42:56 -0700966 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
Andy Hung2ddee192015-12-18 17:34:44 -0800967 !(mEffects.isNonOffloadableEffectEnabled() || mMasterMono)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700968 profile = getProfileForDirectOutput(device,
969 samplingRate,
970 format,
971 channelMask,
972 (audio_output_flags_t)flags);
973 }
974
Eric Laurent1c333e22014-05-20 10:48:17 -0700975 if (profile != 0) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700976 sp<SwAudioOutputDescriptor> outputDesc = NULL;
Eric Laurente552edb2014-03-10 17:42:56 -0700977
978 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -0700979 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700980 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
981 outputDesc = desc;
Kevin Rocard551061a2017-02-06 15:59:29 -0800982 // reuse direct output if currently open by the same client
983 // and configured with same parameters
Eric Laurente552edb2014-03-10 17:42:56 -0700984 if ((samplingRate == outputDesc->mSamplingRate) &&
Kevin Rocard551061a2017-02-06 15:59:29 -0800985 audio_formats_match(format, outputDesc->mFormat) &&
986 (channelMask == outputDesc->mChannelMask)) {
Kevin Rocard169753c2017-03-06 14:18:23 -0800987 if (session == outputDesc->mDirectClientSession) {
Kevin Rocard551061a2017-02-06 15:59:29 -0800988 outputDesc->mDirectOpenCount++;
Kevin Rocard169753c2017-03-06 14:18:23 -0800989 ALOGV("getOutput() reusing direct output %d for session %d",
990 mOutputs.keyAt(i), session);
Kevin Rocard551061a2017-02-06 15:59:29 -0800991 return mOutputs.keyAt(i);
992 } else {
Kevin Rocard169753c2017-03-06 14:18:23 -0800993 ALOGV("getOutput() do not reuse direct output because current client (%d) "
994 "is not the same as requesting client (%d)",
995 outputDesc->mDirectClientSession, session);
Kevin Rocard551061a2017-02-06 15:59:29 -0800996 goto non_direct_output;
997 }
Eric Laurente552edb2014-03-10 17:42:56 -0700998 }
999 }
1000 }
1001 // close direct output if currently open and configured with different parameters
1002 if (outputDesc != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07001003 closeOutput(outputDesc->mIoHandle);
Eric Laurente552edb2014-03-10 17:42:56 -07001004 }
Eric Laurent861a6282015-05-18 15:40:16 -07001005
1006 // if the selected profile is offloaded and no offload info was specified,
1007 // create a default one
1008 audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
François Gaffiea8ecc2c2015-11-09 16:10:40 +01001009 if ((profile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
Eric Laurent861a6282015-05-18 15:40:16 -07001010 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
1011 defaultOffloadInfo.sample_rate = samplingRate;
1012 defaultOffloadInfo.channel_mask = channelMask;
1013 defaultOffloadInfo.format = format;
1014 defaultOffloadInfo.stream_type = stream;
1015 defaultOffloadInfo.bit_rate = 0;
1016 defaultOffloadInfo.duration_us = -1;
1017 defaultOffloadInfo.has_video = true; // conservative
1018 defaultOffloadInfo.is_streaming = true; // likely
1019 offloadInfo = &defaultOffloadInfo;
1020 }
1021
Eric Laurentc75307b2015-03-17 15:29:32 -07001022 outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -07001023 outputDesc->mDevice = device;
Eric Laurente552edb2014-03-10 17:42:56 -07001024 outputDesc->mLatency = 0;
Eric Laurent861a6282015-05-18 15:40:16 -07001025 outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001026 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1027 config.sample_rate = samplingRate;
1028 config.channel_mask = channelMask;
1029 config.format = format;
Phil Burk77cce802014-08-04 16:18:15 -07001030 if (offloadInfo != NULL) {
1031 config.offload_info = *offloadInfo;
1032 }
Eric Laurente3014102017-05-03 11:15:43 -07001033 DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromType(device);
1034 String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
1035 : String8("");
Eric Laurent322b4d22015-04-03 15:57:54 -07001036 status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07001037 &output,
1038 &config,
1039 &outputDesc->mDevice,
Eric Laurente3014102017-05-03 11:15:43 -07001040 address,
Eric Laurentcf2c0212014-07-25 16:20:43 -07001041 &outputDesc->mLatency,
1042 outputDesc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -07001043
1044 // only accept an output with the requested parameters
Eric Laurentcf2c0212014-07-25 16:20:43 -07001045 if (status != NO_ERROR ||
1046 (samplingRate != 0 && samplingRate != config.sample_rate) ||
Eric Laurente6930022016-02-11 10:20:40 -08001047 (format != AUDIO_FORMAT_DEFAULT && !audio_formats_match(format, config.format)) ||
Eric Laurentcf2c0212014-07-25 16:20:43 -07001048 (channelMask != 0 && channelMask != config.channel_mask)) {
Eric Laurente552edb2014-03-10 17:42:56 -07001049 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
1050 "format %d %d, channelMask %04x %04x", output, samplingRate,
1051 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
1052 outputDesc->mChannelMask);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001053 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07001054 mpClientInterface->closeOutput(output);
1055 }
Eric Laurenta82797f2015-01-30 11:49:43 -08001056 // fall back to mixer output if possible when the direct output could not be open
Glenn Kasten05ddca52016-02-11 08:17:12 -08001057 if (audio_is_linear_pcm(format) && samplingRate <= SAMPLE_RATE_HZ_MAX) {
Eric Laurenta82797f2015-01-30 11:49:43 -08001058 goto non_direct_output;
1059 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07001060 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001061 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07001062 outputDesc->mSamplingRate = config.sample_rate;
1063 outputDesc->mChannelMask = config.channel_mask;
1064 outputDesc->mFormat = config.format;
1065 outputDesc->mRefCount[stream] = 0;
1066 outputDesc->mStopTime[stream] = 0;
1067 outputDesc->mDirectOpenCount = 1;
Kevin Rocard169753c2017-03-06 14:18:23 -08001068 outputDesc->mDirectClientSession = session;
1069
Eric Laurente552edb2014-03-10 17:42:56 -07001070 addOutput(output, outputDesc);
Eric Laurente552edb2014-03-10 17:42:56 -07001071 mPreviousOutputs = mOutputs;
1072 ALOGV("getOutput() returns new direct output %d", output);
Eric Laurentb52c1522014-05-20 11:27:36 -07001073 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001074 return output;
1075 }
1076
Eric Laurentb732cf52014-09-24 19:08:21 -07001077non_direct_output:
Eric Laurent14cbfca2016-03-17 09:42:16 -07001078
1079 // A request for HW A/V sync cannot fallback to a mixed output because time
1080 // stamps are embedded in audio data
1081 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
1082 return AUDIO_IO_HANDLE_NONE;
1083 }
1084
Eric Laurente552edb2014-03-10 17:42:56 -07001085 // ignoring channel mask due to downmix capability in mixer
1086
1087 // open a non direct output
1088
1089 // for non direct outputs, only PCM is supported
1090 if (audio_is_linear_pcm(format)) {
1091 // get which output is suitable for the specified stream. The actual
1092 // routing change will happen when startOutput() will be called
1093 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1094
Eric Laurent8838a382014-09-08 16:44:28 -07001095 // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
1096 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
1097 output = selectOutput(outputs, flags, format);
Eric Laurente552edb2014-03-10 17:42:56 -07001098 }
1099 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1100 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1101
Eric Laurente552edb2014-03-10 17:42:56 -07001102 return output;
1103}
1104
Eric Laurente0720872014-03-11 09:30:41 -07001105audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
Eric Laurent8838a382014-09-08 16:44:28 -07001106 audio_output_flags_t flags,
1107 audio_format_t format)
Eric Laurente552edb2014-03-10 17:42:56 -07001108{
1109 // select one output among several that provide a path to a particular device or set of
1110 // devices (the list was previously build by getOutputsForDevice()).
1111 // The priority is as follows:
1112 // 1: the output with the highest number of requested policy flags
Eric Laurente6930022016-02-11 10:20:40 -08001113 // 2: the output with the bit depth the closest to the requested one
1114 // 3: the primary output
1115 // 4: the first output in the list
Eric Laurente552edb2014-03-10 17:42:56 -07001116
1117 if (outputs.size() == 0) {
1118 return 0;
1119 }
1120 if (outputs.size() == 1) {
1121 return outputs[0];
1122 }
1123
1124 int maxCommonFlags = 0;
Eric Laurente6930022016-02-11 10:20:40 -08001125 audio_io_handle_t outputForFlags = 0;
1126 audio_io_handle_t outputForPrimary = 0;
1127 audio_io_handle_t outputForFormat = 0;
1128 audio_format_t bestFormat = AUDIO_FORMAT_INVALID;
1129 audio_format_t bestFormatForFlags = AUDIO_FORMAT_INVALID;
Eric Laurente552edb2014-03-10 17:42:56 -07001130
1131 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001132 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -07001133 if (!outputDesc->isDuplicated()) {
Eric Laurent8838a382014-09-08 16:44:28 -07001134 // if a valid format is specified, skip output if not compatible
1135 if (format != AUDIO_FORMAT_INVALID) {
1136 if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
Eric Laurente6930022016-02-11 10:20:40 -08001137 if (!audio_formats_match(format, outputDesc->mFormat)) {
Eric Laurent8838a382014-09-08 16:44:28 -07001138 continue;
1139 }
1140 } else if (!audio_is_linear_pcm(format)) {
1141 continue;
1142 }
Eric Laurente6930022016-02-11 10:20:40 -08001143 if (AudioPort::isBetterFormatMatch(
1144 outputDesc->mFormat, bestFormat, format)) {
1145 outputForFormat = outputs[i];
1146 bestFormat = outputDesc->mFormat;
1147 }
Eric Laurent8838a382014-09-08 16:44:28 -07001148 }
1149
François Gaffiea8ecc2c2015-11-09 16:10:40 +01001150 int commonFlags = popcount(outputDesc->mProfile->getFlags() & flags);
Eric Laurente6930022016-02-11 10:20:40 -08001151 if (commonFlags >= maxCommonFlags) {
1152 if (commonFlags == maxCommonFlags) {
1153 if (AudioPort::isBetterFormatMatch(
1154 outputDesc->mFormat, bestFormatForFlags, format)) {
1155 outputForFlags = outputs[i];
1156 bestFormatForFlags = outputDesc->mFormat;
1157 }
1158 } else {
1159 outputForFlags = outputs[i];
1160 maxCommonFlags = commonFlags;
1161 bestFormatForFlags = outputDesc->mFormat;
1162 }
Eric Laurente552edb2014-03-10 17:42:56 -07001163 ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
1164 }
François Gaffiea8ecc2c2015-11-09 16:10:40 +01001165 if (outputDesc->mProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
Eric Laurente6930022016-02-11 10:20:40 -08001166 outputForPrimary = outputs[i];
Eric Laurente552edb2014-03-10 17:42:56 -07001167 }
1168 }
1169 }
1170
Eric Laurente6930022016-02-11 10:20:40 -08001171 if (outputForFlags != 0) {
1172 return outputForFlags;
Eric Laurente552edb2014-03-10 17:42:56 -07001173 }
Eric Laurente6930022016-02-11 10:20:40 -08001174 if (outputForFormat != 0) {
1175 return outputForFormat;
1176 }
1177 if (outputForPrimary != 0) {
1178 return outputForPrimary;
Eric Laurente552edb2014-03-10 17:42:56 -07001179 }
1180
1181 return outputs[0];
1182}
1183
Eric Laurente0720872014-03-11 09:30:41 -07001184status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001185 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -08001186 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001187{
Paul McLeanaa981192015-03-21 09:55:15 -07001188 ALOGV("startOutput() output %d, stream %d, session %d",
1189 output, stream, session);
Eric Laurente552edb2014-03-10 17:42:56 -07001190 ssize_t index = mOutputs.indexOfKey(output);
1191 if (index < 0) {
1192 ALOGW("startOutput() unknown output %d", output);
1193 return BAD_VALUE;
1194 }
1195
Eric Laurentc75307b2015-03-17 15:29:32 -07001196 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
1197
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001198 // Routing?
1199 mOutputRoutes.incRouteActivity(session);
1200
Eric Laurentc75307b2015-03-17 15:29:32 -07001201 audio_devices_t newDevice;
Eric Laurentc40d9692016-04-13 19:14:13 -07001202 AudioMix *policyMix = NULL;
1203 const char *address = NULL;
Eric Laurentc75307b2015-03-17 15:29:32 -07001204 if (outputDesc->mPolicyMix != NULL) {
Eric Laurentc40d9692016-04-13 19:14:13 -07001205 policyMix = outputDesc->mPolicyMix;
1206 address = policyMix->mDeviceAddress.string();
1207 if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
1208 newDevice = policyMix->mDeviceType;
1209 } else {
1210 newDevice = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
1211 }
Eric Laurent493404d2015-04-21 15:07:36 -07001212 } else if (mOutputRoutes.hasRouteChanged(session)) {
1213 newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001214 checkStrategyRoute(getStrategy(stream), output);
Eric Laurentc75307b2015-03-17 15:29:32 -07001215 } else {
1216 newDevice = AUDIO_DEVICE_NONE;
1217 }
1218
1219 uint32_t delayMs = 0;
1220
Eric Laurentc40d9692016-04-13 19:14:13 -07001221 status_t status = startSource(outputDesc, stream, newDevice, address, &delayMs);
Eric Laurentc75307b2015-03-17 15:29:32 -07001222
1223 if (status != NO_ERROR) {
1224 mOutputRoutes.decRouteActivity(session);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001225 return status;
Eric Laurentc75307b2015-03-17 15:29:32 -07001226 }
1227 // Automatically enable the remote submix input when output is started on a re routing mix
1228 // of type MIX_TYPE_RECORDERS
Eric Laurentc40d9692016-04-13 19:14:13 -07001229 if (audio_is_remote_submix_device(newDevice) && policyMix != NULL &&
1230 policyMix->mMixType == MIX_TYPE_RECORDERS) {
Eric Laurentc75307b2015-03-17 15:29:32 -07001231 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1232 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
Eric Laurentc40d9692016-04-13 19:14:13 -07001233 address,
Eric Laurentc75307b2015-03-17 15:29:32 -07001234 "remote-submix");
1235 }
1236
1237 if (delayMs != 0) {
1238 usleep(delayMs * 1000);
1239 }
1240
1241 return status;
1242}
1243
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07001244status_t AudioPolicyManager::startSource(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurentc75307b2015-03-17 15:29:32 -07001245 audio_stream_type_t stream,
1246 audio_devices_t device,
Eric Laurentc40d9692016-04-13 19:14:13 -07001247 const char *address,
Eric Laurentc75307b2015-03-17 15:29:32 -07001248 uint32_t *delayMs)
1249{
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001250 // cannot start playback of STREAM_TTS if any other output is being used
1251 uint32_t beaconMuteLatency = 0;
Eric Laurentc75307b2015-03-17 15:29:32 -07001252
1253 *delayMs = 0;
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001254 if (stream == AUDIO_STREAM_TTS) {
1255 ALOGV("\t found BEACON stream");
Eric Laurent9459fb02015-08-12 18:36:32 -07001256 if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001257 return INVALID_OPERATION;
1258 } else {
1259 beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1260 }
1261 } else {
1262 // some playback other than beacon starts
1263 beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1264 }
1265
Eric Laurent77305a62016-07-25 16:39:22 -07001266 // force device change if the output is inactive and no audio patch is already present.
Eric Laurent7c1ec5f2015-07-09 14:52:47 -07001267 // check active before incrementing usage count
Eric Laurent77305a62016-07-25 16:39:22 -07001268 bool force = !outputDesc->isActive() &&
1269 (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
Eric Laurent7c1ec5f2015-07-09 14:52:47 -07001270
Eric Laurente552edb2014-03-10 17:42:56 -07001271 // increment usage count for this stream on the requested output:
1272 // NOTE that the usage count is the same for duplicated output and hardware output which is
1273 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1274 outputDesc->changeRefCount(stream, 1);
1275
Eric Laurent36829f92017-04-07 19:04:42 -07001276 if (stream == AUDIO_STREAM_MUSIC) {
1277 selectOutputForMusicEffects();
1278 }
1279
Eric Laurent493404d2015-04-21 15:07:36 -07001280 if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001281 // starting an output being rerouted?
Eric Laurentc75307b2015-03-17 15:29:32 -07001282 if (device == AUDIO_DEVICE_NONE) {
1283 device = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurent275e8e92014-11-30 15:14:47 -08001284 }
Eric Laurent36829f92017-04-07 19:04:42 -07001285
Eric Laurente552edb2014-03-10 17:42:56 -07001286 routing_strategy strategy = getStrategy(stream);
1287 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001288 (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1289 (beaconMuteLatency > 0);
1290 uint32_t waitMs = beaconMuteLatency;
Eric Laurente552edb2014-03-10 17:42:56 -07001291 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001292 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001293 if (desc != outputDesc) {
Eric Laurent77305a62016-07-25 16:39:22 -07001294 // force a device change if any other output is:
1295 // - managed by the same hw module
1296 // - has a current device selection that differs from selected device.
1297 // - supports currently selected device
1298 // - has an active audio patch
Eric Laurente552edb2014-03-10 17:42:56 -07001299 // In this case, the audio HAL must receive the new device selection so that it can
1300 // change the device currently selected by the other active output.
1301 if (outputDesc->sharesHwModuleWith(desc) &&
Eric Laurent77305a62016-07-25 16:39:22 -07001302 desc->device() != device &&
1303 desc->supportedDevices() & device &&
1304 desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07001305 force = true;
1306 }
1307 // wait for audio on other active outputs to be presented when starting
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001308 // a notification so that audio focus effect can propagate, or that a mute/unmute
1309 // event occurred for beacon
Eric Laurente552edb2014-03-10 17:42:56 -07001310 uint32_t latency = desc->latency();
1311 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1312 waitMs = latency;
1313 }
1314 }
1315 }
Eric Laurentdc462862016-07-19 12:29:53 -07001316 uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
Eric Laurente552edb2014-03-10 17:42:56 -07001317
1318 // handle special case for sonification while in call
1319 if (isInCall()) {
1320 handleIncallSonification(stream, true, false);
1321 }
1322
1323 // apply volume rules for current stream and device if necessary
1324 checkAndSetVolume(stream,
Shuhei Miyazaki6fe70332017-07-31 15:21:28 +09001325 mVolumeCurves->getVolumeIndex(stream, outputDesc->device()),
Eric Laurentc75307b2015-03-17 15:29:32 -07001326 outputDesc,
Shuhei Miyazaki6fe70332017-07-31 15:21:28 +09001327 outputDesc->device());
Eric Laurente552edb2014-03-10 17:42:56 -07001328
1329 // update the outputs if starting an output with a stream that can affect notification
1330 // routing
1331 handleNotificationRoutingForStream(stream);
Eric Laurentc722f302014-12-10 11:21:49 -08001332
Eric Laurent2cbe89a2014-12-19 11:49:08 -08001333 // force reevaluating accessibility routing when ringtone or alarm starts
1334 if (strategy == STRATEGY_SONIFICATION) {
1335 mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
1336 }
Eric Laurentdc462862016-07-19 12:29:53 -07001337
1338 if (waitMs > muteWaitMs) {
1339 *delayMs = waitMs - muteWaitMs;
1340 }
Eric Laurente552edb2014-03-10 17:42:56 -07001341 }
Eric Laurentdc462862016-07-19 12:29:53 -07001342
Tomoharu Kasaharaa81f0982018-01-18 20:55:02 +09001343 if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
1344 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
1345 setStrategyMute(STRATEGY_SONIFICATION, true, outputDesc);
1346 }
1347
Eric Laurente552edb2014-03-10 17:42:56 -07001348 return NO_ERROR;
1349}
1350
1351
Eric Laurente0720872014-03-11 09:30:41 -07001352status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001353 audio_stream_type_t stream,
Eric Laurente83b55d2014-11-14 10:06:21 -08001354 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001355{
1356 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1357 ssize_t index = mOutputs.indexOfKey(output);
1358 if (index < 0) {
1359 ALOGW("stopOutput() unknown output %d", output);
1360 return BAD_VALUE;
1361 }
1362
Eric Laurentc75307b2015-03-17 15:29:32 -07001363 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001364
Eric Laurentc75307b2015-03-17 15:29:32 -07001365 if (outputDesc->mRefCount[stream] == 1) {
1366 // Automatically disable the remote submix input when output is stopped on a
1367 // re routing mix of type MIX_TYPE_RECORDERS
1368 if (audio_is_remote_submix_device(outputDesc->mDevice) &&
1369 outputDesc->mPolicyMix != NULL &&
1370 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
1371 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
1372 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08001373 outputDesc->mPolicyMix->mDeviceAddress,
Eric Laurentc75307b2015-03-17 15:29:32 -07001374 "remote-submix");
1375 }
1376 }
1377
1378 // Routing?
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001379 bool forceDeviceUpdate = false;
Eric Laurentc75307b2015-03-17 15:29:32 -07001380 if (outputDesc->mRefCount[stream] > 0) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001381 int activityCount = mOutputRoutes.decRouteActivity(session);
1382 forceDeviceUpdate = (mOutputRoutes.hasRoute(session) && (activityCount == 0));
1383
1384 if (forceDeviceUpdate) {
1385 checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
1386 }
Eric Laurentc75307b2015-03-17 15:29:32 -07001387 }
1388
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001389 return stopSource(outputDesc, stream, forceDeviceUpdate);
Eric Laurentc75307b2015-03-17 15:29:32 -07001390}
1391
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07001392status_t AudioPolicyManager::stopSource(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001393 audio_stream_type_t stream,
1394 bool forceDeviceUpdate)
Eric Laurentc75307b2015-03-17 15:29:32 -07001395{
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07001396 // always handle stream stop, check which stream type is stopping
1397 handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
1398
Eric Laurente552edb2014-03-10 17:42:56 -07001399 // handle special case for sonification while in call
1400 if (isInCall()) {
1401 handleIncallSonification(stream, false, false);
1402 }
1403
1404 if (outputDesc->mRefCount[stream] > 0) {
1405 // decrement usage count of this stream on the output
1406 outputDesc->changeRefCount(stream, -1);
Paul McLeanaa981192015-03-21 09:55:15 -07001407
Eric Laurente552edb2014-03-10 17:42:56 -07001408 // store time at which the stream was stopped - see isStreamActive()
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001409 if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
Eric Laurente552edb2014-03-10 17:42:56 -07001410 outputDesc->mStopTime[stream] = systemTime();
Eric Laurentc75307b2015-03-17 15:29:32 -07001411 audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
Eric Laurente552edb2014-03-10 17:42:56 -07001412 // delay the device switch by twice the latency because stopOutput() is executed when
1413 // the track stop() command is received and at that time the audio track buffer can
1414 // still contain data that needs to be drained. The latency only covers the audio HAL
1415 // and kernel buffers. Also the latency does not always include additional delay in the
1416 // audio path (audio DSP, CODEC ...)
Eric Laurentc75307b2015-03-17 15:29:32 -07001417 setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
Eric Laurente552edb2014-03-10 17:42:56 -07001418
1419 // force restoring the device selection on other active outputs if it differs from the
1420 // one being selected for this output
Eric Laurent57de36c2016-09-28 16:59:11 -07001421 uint32_t delayMs = outputDesc->latency()*2;
Eric Laurente552edb2014-03-10 17:42:56 -07001422 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001423 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurentc75307b2015-03-17 15:29:32 -07001424 if (desc != outputDesc &&
Eric Laurente552edb2014-03-10 17:42:56 -07001425 desc->isActive() &&
1426 outputDesc->sharesHwModuleWith(desc) &&
1427 (newDevice != desc->device())) {
Haynes Mathew George11c499a2016-08-26 12:08:25 -07001428 audio_devices_t newDevice2 = getNewOutputDevice(desc, false /*fromCache*/);
1429 bool force = desc->device() != newDevice2;
Eric Laurentc75307b2015-03-17 15:29:32 -07001430 setOutputDevice(desc,
Haynes Mathew George11c499a2016-08-26 12:08:25 -07001431 newDevice2,
1432 force,
Eric Laurent57de36c2016-09-28 16:59:11 -07001433 delayMs);
1434 // re-apply device specific volume if not done by setOutputDevice()
1435 if (!force) {
1436 applyStreamVolumes(desc, newDevice2, delayMs);
1437 }
Eric Laurente552edb2014-03-10 17:42:56 -07001438 }
1439 }
1440 // update the outputs if stopping one with a stream that can affect notification routing
1441 handleNotificationRoutingForStream(stream);
1442 }
Tomoharu Kasaharaa81f0982018-01-18 20:55:02 +09001443
1444 if (stream == AUDIO_STREAM_ENFORCED_AUDIBLE &&
1445 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
1446 setStrategyMute(STRATEGY_SONIFICATION, false, outputDesc);
1447 }
1448
Eric Laurent36829f92017-04-07 19:04:42 -07001449 if (stream == AUDIO_STREAM_MUSIC) {
1450 selectOutputForMusicEffects();
1451 }
Eric Laurente552edb2014-03-10 17:42:56 -07001452 return NO_ERROR;
1453 } else {
Eric Laurentc75307b2015-03-17 15:29:32 -07001454 ALOGW("stopOutput() refcount is already 0");
Eric Laurente552edb2014-03-10 17:42:56 -07001455 return INVALID_OPERATION;
1456 }
1457}
1458
Eric Laurente83b55d2014-11-14 10:06:21 -08001459void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
Eric Laurentcaf7f482014-11-25 17:50:47 -08001460 audio_stream_type_t stream __unused,
1461 audio_session_t session __unused)
Eric Laurente552edb2014-03-10 17:42:56 -07001462{
1463 ALOGV("releaseOutput() %d", output);
1464 ssize_t index = mOutputs.indexOfKey(output);
1465 if (index < 0) {
1466 ALOGW("releaseOutput() releasing unknown output %d", output);
1467 return;
1468 }
1469
1470#ifdef AUDIO_POLICY_TEST
1471 int testIndex = testOutputIndex(output);
1472 if (testIndex != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001473 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001474 if (outputDesc->isActive()) {
1475 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01001476 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07001477 mTestOutputs[testIndex] = 0;
1478 }
1479 return;
1480 }
1481#endif //AUDIO_POLICY_TEST
1482
Paul McLeanaa981192015-03-21 09:55:15 -07001483 // Routing
1484 mOutputRoutes.removeRoute(session);
1485
Eric Laurentc75307b2015-03-17 15:29:32 -07001486 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(index);
Eric Laurent3b73df72014-03-11 09:06:29 -07001487 if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
Eric Laurente552edb2014-03-10 17:42:56 -07001488 if (desc->mDirectOpenCount <= 0) {
1489 ALOGW("releaseOutput() invalid open count %d for output %d",
1490 desc->mDirectOpenCount, output);
1491 return;
1492 }
1493 if (--desc->mDirectOpenCount == 0) {
1494 closeOutput(output);
Eric Laurentb52c1522014-05-20 11:27:36 -07001495 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001496 }
1497 }
1498}
1499
1500
Eric Laurentcaf7f482014-11-25 17:50:47 -08001501status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
1502 audio_io_handle_t *input,
1503 audio_session_t session,
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001504 uid_t uid,
Eric Laurent20b9ef02016-12-05 11:03:16 -08001505 const audio_config_base_t *config,
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001506 audio_input_flags_t flags,
Eric Laurent2ac76942017-06-22 17:17:09 -07001507 audio_port_handle_t *selectedDeviceId,
Eric Laurent20b9ef02016-12-05 11:03:16 -08001508 input_type_t *inputType,
1509 audio_port_handle_t *portId)
Eric Laurente552edb2014-03-10 17:42:56 -07001510{
Eric Laurentcaf7f482014-11-25 17:50:47 -08001511 ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
1512 "session %d, flags %#x",
Eric Laurent20b9ef02016-12-05 11:03:16 -08001513 attr->source, config->sample_rate, config->format, config->channel_mask, session, flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001514
Eric Laurentad2e7b92017-09-14 20:06:42 -07001515 status_t status = NO_ERROR;
Eric Laurent275e8e92014-11-30 15:14:47 -08001516 // handle legacy remote submix case where the address was not always specified
1517 String8 address = String8("");
Eric Laurentc447ded2015-01-06 08:47:05 -08001518 audio_source_t halInputSource;
Eric Laurentad2e7b92017-09-14 20:06:42 -07001519 audio_source_t inputSource = attr->source;
Eric Laurentc722f302014-12-10 11:21:49 -08001520 AudioMix *policyMix = NULL;
Eric Laurentad2e7b92017-09-14 20:06:42 -07001521 DeviceVector inputDevices;
Eric Laurent20b9ef02016-12-05 11:03:16 -08001522
Paul McLean466dc8e2015-04-17 13:15:36 -06001523 // Explicit routing?
1524 sp<DeviceDescriptor> deviceDesc;
Eric Laurent2ac76942017-06-22 17:17:09 -07001525 if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
1526 for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
1527 if (mAvailableInputDevices[i]->getId() == *selectedDeviceId) {
1528 deviceDesc = mAvailableInputDevices[i];
1529 break;
1530 }
Paul McLean466dc8e2015-04-17 13:15:36 -06001531 }
1532 }
Eric Laurent8c7e6da2015-04-21 17:37:00 -07001533 mInputRoutes.addRoute(session, SessionRoute::STREAM_TYPE_NA, inputSource, deviceDesc, uid);
Paul McLean466dc8e2015-04-17 13:15:36 -06001534
Eric Laurentad2e7b92017-09-14 20:06:42 -07001535 // special case for mmap capture: if an input IO handle is specified, we reuse this input if
1536 // possible
1537 if ((flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) == AUDIO_INPUT_FLAG_MMAP_NOIRQ &&
1538 *input != AUDIO_IO_HANDLE_NONE) {
1539 ssize_t index = mInputs.indexOfKey(*input);
1540 if (index < 0) {
1541 ALOGW("getInputForAttr() unknown MMAP input %d", *input);
1542 status = BAD_VALUE;
1543 goto error;
1544 }
1545 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1546 sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1547 if (audioSession == 0) {
1548 ALOGW("getInputForAttr() unknown session %d on input %d", session, *input);
1549 status = BAD_VALUE;
1550 goto error;
1551 }
1552 // For MMAP mode, the first call to getInputForAttr() is made on behalf of audioflinger.
1553 // The second call is for the first active client and sets the UID. Any further call
1554 // corresponds to a new client and is only permitted from the same UId.
1555 if (audioSession->openCount() == 1) {
1556 audioSession->setUid(uid);
1557 } else if (audioSession->uid() != uid) {
1558 ALOGW("getInputForAttr() bad uid %d for session %d uid %d",
1559 uid, session, audioSession->uid());
1560 status = INVALID_OPERATION;
1561 goto error;
1562 }
1563 audioSession->changeOpenCount(1);
1564 *inputType = API_INPUT_LEGACY;
1565 if (*portId == AUDIO_PORT_HANDLE_NONE) {
1566 *portId = AudioPort::getNextUniqueId();
1567 }
1568 inputDevices = mAvailableInputDevices.getDevicesFromType(inputDesc->mDevice);
1569 *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
1570 : AUDIO_PORT_HANDLE_NONE;
1571 ALOGI("%s reusing MMAP input %d for session %d", __FUNCTION__, *input, session);
1572
1573 return NO_ERROR;
1574 }
1575
1576 *input = AUDIO_IO_HANDLE_NONE;
1577 *inputType = API_INPUT_INVALID;
1578
1579 if (inputSource == AUDIO_SOURCE_DEFAULT) {
1580 inputSource = AUDIO_SOURCE_MIC;
1581 }
1582 halInputSource = inputSource;
1583
1584 // TODO: check for existing client for this port ID
1585 if (*portId == AUDIO_PORT_HANDLE_NONE) {
1586 *portId = AudioPort::getNextUniqueId();
1587 }
1588
1589 audio_devices_t device;
1590
Eric Laurentc447ded2015-01-06 08:47:05 -08001591 if (inputSource == AUDIO_SOURCE_REMOTE_SUBMIX &&
Eric Laurent275e8e92014-11-30 15:14:47 -08001592 strncmp(attr->tags, "addr=", strlen("addr=")) == 0) {
Eric Laurentad2e7b92017-09-14 20:06:42 -07001593 status = mPolicyMixes.getInputMixForAttr(*attr, &policyMix);
1594 if (status != NO_ERROR) {
1595 goto error;
François Gaffie036e1e92015-03-19 10:16:24 +01001596 }
1597 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
Eric Laurent275e8e92014-11-30 15:14:47 -08001598 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
1599 address = String8(attr->tags + strlen("addr="));
Eric Laurent275e8e92014-11-30 15:14:47 -08001600 } else {
Eric Laurentc447ded2015-01-06 08:47:05 -08001601 device = getDeviceAndMixForInputSource(inputSource, &policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08001602 if (device == AUDIO_DEVICE_NONE) {
Eric Laurentc447ded2015-01-06 08:47:05 -08001603 ALOGW("getInputForAttr() could not find device for source %d", inputSource);
Eric Laurentad2e7b92017-09-14 20:06:42 -07001604 status = BAD_VALUE;
1605 goto error;
Eric Laurent275e8e92014-11-30 15:14:47 -08001606 }
Eric Laurentc722f302014-12-10 11:21:49 -08001607 if (policyMix != NULL) {
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08001608 address = policyMix->mDeviceAddress;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001609 if (policyMix->mMixType == MIX_TYPE_RECORDERS) {
1610 // there is an external policy, but this input is attached to a mix of recorders,
1611 // meaning it receives audio injected into the framework, so the recorder doesn't
1612 // know about it and is therefore considered "legacy"
1613 *inputType = API_INPUT_LEGACY;
1614 } else {
1615 // recording a mix of players defined by an external policy, we're rerouting for
1616 // an external policy
1617 *inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
1618 }
Eric Laurentc722f302014-12-10 11:21:49 -08001619 } else if (audio_is_remote_submix_device(device)) {
1620 address = String8("0");
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001621 *inputType = API_INPUT_MIX_CAPTURE;
Eric Laurent82db2692015-08-07 13:59:42 -07001622 } else if (device == AUDIO_DEVICE_IN_TELEPHONY_RX) {
1623 *inputType = API_INPUT_TELEPHONY_RX;
Jean-Michel Trivi97bb33f2014-12-12 16:23:43 -08001624 } else {
1625 *inputType = API_INPUT_LEGACY;
Eric Laurentc722f302014-12-10 11:21:49 -08001626 }
Ravi Kumar Alamandab367f5b2015-08-25 08:21:37 -07001627
Eric Laurent599c7582015-12-07 18:05:55 -08001628 }
1629
1630 *input = getInputForDevice(device, address, session, uid, inputSource,
Eric Laurent20b9ef02016-12-05 11:03:16 -08001631 config->sample_rate, config->format, config->channel_mask, flags,
Eric Laurent599c7582015-12-07 18:05:55 -08001632 policyMix);
1633 if (*input == AUDIO_IO_HANDLE_NONE) {
Eric Laurentad2e7b92017-09-14 20:06:42 -07001634 status = INVALID_OPERATION;
1635 goto error;
Eric Laurent599c7582015-12-07 18:05:55 -08001636 }
Eric Laurent20b9ef02016-12-05 11:03:16 -08001637
Eric Laurentad2e7b92017-09-14 20:06:42 -07001638 inputDevices = mAvailableInputDevices.getDevicesFromType(device);
Eric Laurent2ac76942017-06-22 17:17:09 -07001639 *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
1640 : AUDIO_PORT_HANDLE_NONE;
1641
1642 ALOGV("getInputForAttr() returns input %d type %d selectedDeviceId %d",
1643 *input, *inputType, *selectedDeviceId);
1644
Eric Laurent599c7582015-12-07 18:05:55 -08001645 return NO_ERROR;
Eric Laurentad2e7b92017-09-14 20:06:42 -07001646
1647error:
1648 mInputRoutes.removeRoute(session);
1649 return status;
Eric Laurent599c7582015-12-07 18:05:55 -08001650}
1651
1652
1653audio_io_handle_t AudioPolicyManager::getInputForDevice(audio_devices_t device,
1654 String8 address,
1655 audio_session_t session,
1656 uid_t uid,
1657 audio_source_t inputSource,
1658 uint32_t samplingRate,
1659 audio_format_t format,
1660 audio_channel_mask_t channelMask,
1661 audio_input_flags_t flags,
1662 AudioMix *policyMix)
1663{
1664 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
1665 audio_source_t halInputSource = inputSource;
1666 bool isSoundTrigger = false;
1667
1668 if (inputSource == AUDIO_SOURCE_HOTWORD) {
1669 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1670 if (index >= 0) {
1671 input = mSoundTriggerSessions.valueFor(session);
1672 isSoundTrigger = true;
1673 flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
1674 ALOGV("SoundTrigger capture on session %d input %d", session, input);
1675 } else {
1676 halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
Eric Laurent5dbe4712014-09-19 19:04:57 -07001677 }
Haynes Mathew George851d3ff2017-06-19 20:01:57 -07001678 } else if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION &&
Haynes Mathew George851d3ff2017-06-19 20:01:57 -07001679 audio_is_linear_pcm(format)) {
1680 flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_VOIP_TX);
Eric Laurent5dbe4712014-09-19 19:04:57 -07001681 }
1682
Andy Hungf129b032015-04-07 13:45:50 -07001683 // find a compatible input profile (not necessarily identical in parameters)
1684 sp<IOProfile> profile;
1685 // samplingRate and flags may be updated by getInputProfile
Glenn Kasten05ddca52016-02-11 08:17:12 -08001686 uint32_t profileSamplingRate = (samplingRate == 0) ? SAMPLE_RATE_HZ_DEFAULT : samplingRate;
Andy Hungf129b032015-04-07 13:45:50 -07001687 audio_format_t profileFormat = format;
1688 audio_channel_mask_t profileChannelMask = channelMask;
1689 audio_input_flags_t profileFlags = flags;
1690 for (;;) {
Eric Laurent275e8e92014-11-30 15:14:47 -08001691 profile = getInputProfile(device, address,
Andy Hungf129b032015-04-07 13:45:50 -07001692 profileSamplingRate, profileFormat, profileChannelMask,
1693 profileFlags);
1694 if (profile != 0) {
1695 break; // success
Eric Laurent05067782016-06-01 18:27:28 -07001696 } else if (profileFlags & AUDIO_INPUT_FLAG_RAW) {
1697 profileFlags = (audio_input_flags_t) (profileFlags & ~AUDIO_INPUT_FLAG_RAW); // retry
Andy Hungf129b032015-04-07 13:45:50 -07001698 } else if (profileFlags != AUDIO_INPUT_FLAG_NONE) {
1699 profileFlags = AUDIO_INPUT_FLAG_NONE; // retry
1700 } else { // fail
Eric Laurent599c7582015-12-07 18:05:55 -08001701 ALOGW("getInputForDevice() could not find profile for device 0x%X,"
1702 "samplingRate %u, format %#x, channelMask 0x%X, flags %#x",
Andy Hungf129b032015-04-07 13:45:50 -07001703 device, samplingRate, format, channelMask, flags);
Eric Laurent599c7582015-12-07 18:05:55 -08001704 return input;
Eric Laurent5dbe4712014-09-19 19:04:57 -07001705 }
Eric Laurente552edb2014-03-10 17:42:56 -07001706 }
Glenn Kasten05ddca52016-02-11 08:17:12 -08001707 // Pick input sampling rate if not specified by client
1708 if (samplingRate == 0) {
1709 samplingRate = profileSamplingRate;
1710 }
Eric Laurente552edb2014-03-10 17:42:56 -07001711
Eric Laurent322b4d22015-04-03 15:57:54 -07001712 if (profile->getModuleHandle() == 0) {
1713 ALOGE("getInputForAttr(): HW module %s not opened", profile->getModuleName());
Eric Laurent599c7582015-12-07 18:05:55 -08001714 return input;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001715 }
1716
Eric Laurent599c7582015-12-07 18:05:55 -08001717 sp<AudioSession> audioSession = new AudioSession(session,
1718 inputSource,
1719 format,
1720 samplingRate,
1721 channelMask,
1722 flags,
1723 uid,
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08001724 isSoundTrigger,
1725 policyMix, mpClientInterface);
Eric Laurent599c7582015-12-07 18:05:55 -08001726
Eric Laurent74708e72017-04-07 17:13:42 -07001727// FIXME: disable concurrent capture until UI is ready
1728#if 0
Eric Laurent599c7582015-12-07 18:05:55 -08001729 // reuse an open input if possible
Eric Laurent555530a2017-02-07 18:17:24 -08001730 sp<AudioInputDescriptor> reusedInputDesc;
Eric Laurent599c7582015-12-07 18:05:55 -08001731 for (size_t i = 0; i < mInputs.size(); i++) {
1732 sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
Eric Laurentfb66dd92016-01-28 18:32:03 -08001733 // reuse input if:
1734 // - it shares the same profile
1735 // AND
1736 // - it is not a reroute submix input
1737 // AND
1738 // - it is: not used for sound trigger
1739 // OR
1740 // used for sound trigger and all clients use the same session ID
1741 //
1742 if ((profile == desc->mProfile) &&
1743 (isSoundTrigger == desc->isSoundTrigger()) &&
1744 !is_virtual_input_device(device)) {
Eric Laurent599c7582015-12-07 18:05:55 -08001745
1746 sp<AudioSession> as = desc->getAudioSession(session);
1747 if (as != 0) {
1748 // do not allow unmatching properties on same session
1749 if (as->matches(audioSession)) {
1750 as->changeOpenCount(1);
1751 } else {
1752 ALOGW("getInputForDevice() record with different attributes"
1753 " exists for session %d", session);
Eric Laurent555530a2017-02-07 18:17:24 -08001754 continue;
Eric Laurent599c7582015-12-07 18:05:55 -08001755 }
Eric Laurentfb66dd92016-01-28 18:32:03 -08001756 } else if (isSoundTrigger) {
Eric Laurent555530a2017-02-07 18:17:24 -08001757 continue;
Eric Laurentfb66dd92016-01-28 18:32:03 -08001758 }
Eric Laurentbb948092017-01-23 18:33:30 -08001759
Eric Laurent555530a2017-02-07 18:17:24 -08001760 // Reuse the already opened input stream on this profile if:
1761 // - the new capture source is background OR
1762 // - the path requested configurations match OR
1763 // - the new source priority is less than the highest source priority on this input
1764 // If the input stream cannot be reused, close it before opening a new stream
1765 // on the same profile for the new client so that the requested path configuration
1766 // can be selected.
1767 if (!isConcurrentSource(inputSource) &&
Eric Laurentbb948092017-01-23 18:33:30 -08001768 ((desc->mSamplingRate != samplingRate ||
Eric Laurentfb66dd92016-01-28 18:32:03 -08001769 desc->mChannelMask != channelMask ||
Eric Laurente6930022016-02-11 10:20:40 -08001770 !audio_formats_match(desc->mFormat, format)) &&
Eric Laurentfb66dd92016-01-28 18:32:03 -08001771 (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
Eric Laurentbb948092017-01-23 18:33:30 -08001772 source_priority(inputSource)))) {
Eric Laurent555530a2017-02-07 18:17:24 -08001773 reusedInputDesc = desc;
1774 continue;
Eric Laurent599c7582015-12-07 18:05:55 -08001775 } else {
1776 desc->addAudioSession(session, audioSession);
Eric Laurentfb66dd92016-01-28 18:32:03 -08001777 ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
1778 return mInputs.keyAt(i);
Eric Laurent599c7582015-12-07 18:05:55 -08001779 }
Eric Laurent599c7582015-12-07 18:05:55 -08001780 }
1781 }
Eric Laurent599c7582015-12-07 18:05:55 -08001782
Eric Laurent555530a2017-02-07 18:17:24 -08001783 if (reusedInputDesc != 0) {
1784 AudioSessionCollection sessions = reusedInputDesc->getAudioSessions(false /*activeOnly*/);
1785 for (size_t j = 0; j < sessions.size(); j++) {
1786 audio_session_t currentSession = sessions.keyAt(j);
1787 stopInput(reusedInputDesc->mIoHandle, currentSession);
1788 releaseInput(reusedInputDesc->mIoHandle, currentSession);
1789 }
1790 }
Eric Laurent74708e72017-04-07 17:13:42 -07001791#endif
Eric Laurent555530a2017-02-07 18:17:24 -08001792
Eric Laurentcf2c0212014-07-25 16:20:43 -07001793 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
Andy Hungf129b032015-04-07 13:45:50 -07001794 config.sample_rate = profileSamplingRate;
1795 config.channel_mask = profileChannelMask;
1796 config.format = profileFormat;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001797
Eric Laurente3014102017-05-03 11:15:43 -07001798 if (address == "") {
1799 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(device);
1800 // the inputs vector must be of size 1, but we don't want to crash here
1801 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
1802 }
1803
Eric Laurent322b4d22015-04-03 15:57:54 -07001804 status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
Eric Laurent599c7582015-12-07 18:05:55 -08001805 &input,
Eric Laurentcf2c0212014-07-25 16:20:43 -07001806 &config,
1807 &device,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07001808 address,
Eric Laurent1c9c2cc2014-08-28 19:37:25 -07001809 halInputSource,
Andy Hungf129b032015-04-07 13:45:50 -07001810 profileFlags);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001811
1812 // only accept input with the exact requested set of parameters
Eric Laurent599c7582015-12-07 18:05:55 -08001813 if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE ||
Andy Hungf129b032015-04-07 13:45:50 -07001814 (profileSamplingRate != config.sample_rate) ||
Eric Laurente6930022016-02-11 10:20:40 -08001815 !audio_formats_match(profileFormat, config.format) ||
Andy Hungf129b032015-04-07 13:45:50 -07001816 (profileChannelMask != config.channel_mask)) {
Eric Laurent599c7582015-12-07 18:05:55 -08001817 ALOGW("getInputForAttr() failed opening input: samplingRate %d"
1818 ", format %d, channelMask %x",
Eric Laurentcf2c0212014-07-25 16:20:43 -07001819 samplingRate, format, channelMask);
Eric Laurent599c7582015-12-07 18:05:55 -08001820 if (input != AUDIO_IO_HANDLE_NONE) {
1821 mpClientInterface->closeInput(input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001822 }
Eric Laurent599c7582015-12-07 18:05:55 -08001823 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001824 }
1825
Eric Laurent1f2f2232014-06-02 12:01:23 -07001826 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
Andy Hungf129b032015-04-07 13:45:50 -07001827 inputDesc->mSamplingRate = profileSamplingRate;
1828 inputDesc->mFormat = profileFormat;
1829 inputDesc->mChannelMask = profileChannelMask;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001830 inputDesc->mDevice = device;
Eric Laurentc722f302014-12-10 11:21:49 -08001831 inputDesc->mPolicyMix = policyMix;
Eric Laurent599c7582015-12-07 18:05:55 -08001832 inputDesc->addAudioSession(session, audioSession);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001833
Eric Laurent599c7582015-12-07 18:05:55 -08001834 addInput(input, inputDesc);
Eric Laurentb52c1522014-05-20 11:27:36 -07001835 mpClientInterface->onAudioPortListUpdate();
Paul McLean466dc8e2015-04-17 13:15:36 -06001836
Eric Laurent599c7582015-12-07 18:05:55 -08001837 return input;
Eric Laurente552edb2014-03-10 17:42:56 -07001838}
1839
Eric Laurentbb948092017-01-23 18:33:30 -08001840//static
1841bool AudioPolicyManager::isConcurrentSource(audio_source_t source)
1842{
1843 return (source == AUDIO_SOURCE_HOTWORD) ||
1844 (source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
1845 (source == AUDIO_SOURCE_FM_TUNER);
1846}
1847
Eric Laurentfb66dd92016-01-28 18:32:03 -08001848bool AudioPolicyManager::isConcurentCaptureAllowed(const sp<AudioInputDescriptor>& inputDesc,
1849 const sp<AudioSession>& audioSession)
1850{
1851 // Do not allow capture if an active voice call is using a software patch and
1852 // the call TX source device is on the same HW module.
1853 // FIXME: would be better to refine to only inputs whose profile connects to the
1854 // call TX device but this information is not in the audio patch
1855 if (mCallTxPatch != 0 &&
1856 inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1857 return false;
1858 }
1859
1860 // starting concurrent capture is enabled if:
1861 // 1) capturing for re-routing
1862 // 2) capturing for HOTWORD source
1863 // 3) capturing for FM TUNER source
1864 // 3) All other active captures are either for re-routing or HOTWORD
1865
1866 if (is_virtual_input_device(inputDesc->mDevice) ||
Eric Laurentbb948092017-01-23 18:33:30 -08001867 isConcurrentSource(audioSession->inputSource())) {
Eric Laurentfb66dd92016-01-28 18:32:03 -08001868 return true;
1869 }
1870
1871 Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
1872 for (size_t i = 0; i < activeInputs.size(); i++) {
1873 sp<AudioInputDescriptor> activeInput = activeInputs[i];
Eric Laurentbb948092017-01-23 18:33:30 -08001874 if (!isConcurrentSource(activeInput->inputSource(true)) &&
Eric Laurentfb66dd92016-01-28 18:32:03 -08001875 !is_virtual_input_device(activeInput->mDevice)) {
1876 return false;
1877 }
1878 }
1879
1880 return true;
1881}
1882
Chris Thornton2b864642017-06-27 21:26:07 -07001883// FIXME: remove when concurrent capture is ready. This is a hack to work around bug b/63083537.
1884bool AudioPolicyManager::soundTriggerSupportsConcurrentCapture() {
1885 if (!mHasComputedSoundTriggerSupportsConcurrentCapture) {
1886 bool soundTriggerSupportsConcurrentCapture = false;
1887 unsigned int numModules = 0;
1888 struct sound_trigger_module_descriptor* nModules = NULL;
1889
1890 status_t status = SoundTrigger::listModules(nModules, &numModules);
1891 if (status == NO_ERROR && numModules != 0) {
1892 nModules = (struct sound_trigger_module_descriptor*) calloc(
1893 numModules, sizeof(struct sound_trigger_module_descriptor));
1894 if (nModules == NULL) {
1895 // We failed to malloc the buffer, so just say no for now, and hope that we have more
1896 // ram the next time this function is called.
1897 ALOGE("Failed to allocate buffer for module descriptors");
1898 return false;
1899 }
1900
1901 status = SoundTrigger::listModules(nModules, &numModules);
1902 if (status == NO_ERROR) {
1903 soundTriggerSupportsConcurrentCapture = true;
1904 for (size_t i = 0; i < numModules; ++i) {
1905 soundTriggerSupportsConcurrentCapture &=
1906 nModules[i].properties.concurrent_capture;
1907 }
1908 }
1909 free(nModules);
1910 }
1911 mSoundTriggerSupportsConcurrentCapture = soundTriggerSupportsConcurrentCapture;
1912 mHasComputedSoundTriggerSupportsConcurrentCapture = true;
1913 }
1914 return mSoundTriggerSupportsConcurrentCapture;
1915}
1916
Eric Laurentfb66dd92016-01-28 18:32:03 -08001917
Eric Laurent4dc68062014-07-28 17:26:49 -07001918status_t AudioPolicyManager::startInput(audio_io_handle_t input,
Eric Laurentfb66dd92016-01-28 18:32:03 -08001919 audio_session_t session,
1920 concurrency_type__mask_t *concurrency)
Eric Laurente552edb2014-03-10 17:42:56 -07001921{
1922 ALOGV("startInput() input %d", input);
Eric Laurentfb66dd92016-01-28 18:32:03 -08001923 *concurrency = API_INPUT_CONCURRENCY_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001924 ssize_t index = mInputs.indexOfKey(input);
1925 if (index < 0) {
1926 ALOGW("startInput() unknown input %d", input);
1927 return BAD_VALUE;
1928 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001929 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001930
Eric Laurent599c7582015-12-07 18:05:55 -08001931 sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
1932 if (audioSession == 0) {
Eric Laurent4dc68062014-07-28 17:26:49 -07001933 ALOGW("startInput() unknown session %d on input %d", session, input);
1934 return BAD_VALUE;
1935 }
1936
Eric Laurent74708e72017-04-07 17:13:42 -07001937// FIXME: disable concurrent capture until UI is ready
1938#if 0
Eric Laurentfb66dd92016-01-28 18:32:03 -08001939 if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
1940 ALOGW("startInput(%d) failed: other input already started", input);
1941 return INVALID_OPERATION;
1942 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001943
Eric Laurentfb66dd92016-01-28 18:32:03 -08001944 if (isInCall()) {
1945 *concurrency |= API_INPUT_CONCURRENCY_CALL;
1946 }
Eric Laurentf7c50102016-09-30 15:19:43 -07001947 if (mInputs.activeInputsCountOnDevices() != 0) {
Eric Laurentfb66dd92016-01-28 18:32:03 -08001948 *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
Eric Laurente552edb2014-03-10 17:42:56 -07001949 }
Eric Laurent74708e72017-04-07 17:13:42 -07001950#else
1951 if (!is_virtual_input_device(inputDesc->mDevice)) {
1952 if (mCallTxPatch != 0 &&
1953 inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
1954 ALOGW("startInput(%d) failed: call in progress", input);
1955 return INVALID_OPERATION;
1956 }
1957
1958 Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
1959 for (size_t i = 0; i < activeInputs.size(); i++) {
1960 sp<AudioInputDescriptor> activeDesc = activeInputs[i];
1961
1962 if (is_virtual_input_device(activeDesc->mDevice)) {
1963 continue;
1964 }
1965
Eric Laurentcb4dae22017-07-01 19:39:32 -07001966 if ((audioSession->flags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0 &&
1967 activeDesc->getId() == inputDesc->getId()) {
1968 continue;
1969 }
1970
Eric Laurent74708e72017-04-07 17:13:42 -07001971 audio_source_t activeSource = activeDesc->inputSource(true);
1972 if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
1973 if (activeSource == AUDIO_SOURCE_HOTWORD) {
1974 if (activeDesc->hasPreemptedSession(session)) {
1975 ALOGW("startInput(%d) failed for HOTWORD: "
1976 "other input %d already started for HOTWORD",
1977 input, activeDesc->mIoHandle);
1978 return INVALID_OPERATION;
1979 }
1980 } else {
1981 ALOGV("startInput(%d) failed for HOTWORD: other input %d already started",
1982 input, activeDesc->mIoHandle);
1983 return INVALID_OPERATION;
1984 }
1985 } else {
1986 if (activeSource != AUDIO_SOURCE_HOTWORD) {
1987 ALOGW("startInput(%d) failed: other input %d already started",
1988 input, activeDesc->mIoHandle);
1989 return INVALID_OPERATION;
1990 }
1991 }
1992 }
1993
Chris Thornton2b864642017-06-27 21:26:07 -07001994 // We only need to check if the sound trigger session supports concurrent capture if the
1995 // input is also a sound trigger input. Otherwise, we should preempt any hotword stream
1996 // that's running.
1997 const bool allowConcurrentWithSoundTrigger =
1998 inputDesc->isSoundTrigger() ? soundTriggerSupportsConcurrentCapture() : false;
1999
Eric Laurent74708e72017-04-07 17:13:42 -07002000 // if capture is allowed, preempt currently active HOTWORD captures
2001 for (size_t i = 0; i < activeInputs.size(); i++) {
2002 sp<AudioInputDescriptor> activeDesc = activeInputs[i];
2003
2004 if (is_virtual_input_device(activeDesc->mDevice)) {
2005 continue;
2006 }
2007
Chris Thornton2b864642017-06-27 21:26:07 -07002008 if (allowConcurrentWithSoundTrigger && activeDesc->isSoundTrigger()) {
2009 continue;
2010 }
2011
Eric Laurent74708e72017-04-07 17:13:42 -07002012 audio_source_t activeSource = activeDesc->inputSource(true);
2013 if (activeSource == AUDIO_SOURCE_HOTWORD) {
2014 AudioSessionCollection activeSessions =
2015 activeDesc->getAudioSessions(true /*activeOnly*/);
2016 audio_session_t activeSession = activeSessions.keyAt(0);
2017 audio_io_handle_t activeHandle = activeDesc->mIoHandle;
2018 SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
2019 sessions.add(activeSession);
2020 inputDesc->setPreemptedSessions(sessions);
2021 stopInput(activeHandle, activeSession);
2022 releaseInput(activeHandle, activeSession);
2023 ALOGV("startInput(%d) for HOTWORD preempting HOTWORD input %d",
2024 input, activeDesc->mIoHandle);
2025 }
2026 }
2027 }
2028#endif
Eric Laurente552edb2014-03-10 17:42:56 -07002029
Eric Laurent313d1e72016-01-29 09:56:57 -08002030 // increment activity count before calling getNewInputDevice() below as only active sessions
2031 // are considered for device selection
2032 audioSession->changeActiveCount(1);
2033
Eric Laurent8c7e6da2015-04-21 17:37:00 -07002034 // Routing?
2035 mInputRoutes.incRouteActivity(session);
2036
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002037 if (audioSession->activeCount() == 1 || mInputRoutes.hasRouteChanged(session)) {
Eric Laurent271a93e2016-09-29 14:47:06 -07002038 // indicate active capture to sound trigger service if starting capture from a mic on
2039 // primary HW module
Eric Laurentf7c50102016-09-30 15:19:43 -07002040 audio_devices_t device = getNewInputDevice(inputDesc);
Eric Laurent271a93e2016-09-29 14:47:06 -07002041 setInputDevice(input, device, true /* force */);
Eric Laurente552edb2014-03-10 17:42:56 -07002042
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002043 if (inputDesc->getAudioSessionCount(true/*activeOnly*/) == 1) {
2044 // if input maps to a dynamic policy with an activity listener, notify of state change
2045 if ((inputDesc->mPolicyMix != NULL)
2046 && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2047 mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2048 MIX_STATE_MIXING);
Eric Laurentc722f302014-12-10 11:21:49 -08002049 }
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002050
Eric Laurentf7c50102016-09-30 15:19:43 -07002051 audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
2052 if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Eric Laurent05b345e2016-11-18 12:36:27 -08002053 mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1) {
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002054 SoundTrigger::setCaptureState(true);
2055 }
2056
2057 // automatically enable the remote submix output when input is started if not
2058 // used by a policy mix of type MIX_TYPE_RECORDERS
2059 // For remote submix (a virtual device), we open only one input per capture request.
2060 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
2061 String8 address = String8("");
2062 if (inputDesc->mPolicyMix == NULL) {
2063 address = String8("0");
2064 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2065 address = inputDesc->mPolicyMix->mDeviceAddress;
2066 }
2067 if (address != "") {
2068 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2069 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2070 address, "remote-submix");
2071 }
Eric Laurentc722f302014-12-10 11:21:49 -08002072 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07002073 }
Eric Laurente552edb2014-03-10 17:42:56 -07002074 }
2075
Eric Laurent599c7582015-12-07 18:05:55 -08002076 ALOGV("AudioPolicyManager::startInput() input source = %d", audioSession->inputSource());
Eric Laurente552edb2014-03-10 17:42:56 -07002077
Eric Laurente552edb2014-03-10 17:42:56 -07002078 return NO_ERROR;
2079}
2080
Eric Laurent4dc68062014-07-28 17:26:49 -07002081status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
2082 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07002083{
2084 ALOGV("stopInput() input %d", input);
2085 ssize_t index = mInputs.indexOfKey(input);
2086 if (index < 0) {
2087 ALOGW("stopInput() unknown input %d", input);
2088 return BAD_VALUE;
2089 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07002090 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07002091
Eric Laurent599c7582015-12-07 18:05:55 -08002092 sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
Eric Laurent4dc68062014-07-28 17:26:49 -07002093 if (index < 0) {
2094 ALOGW("stopInput() unknown session %d on input %d", session, input);
2095 return BAD_VALUE;
2096 }
2097
Eric Laurent599c7582015-12-07 18:05:55 -08002098 if (audioSession->activeCount() == 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07002099 ALOGW("stopInput() input %d already stopped", input);
2100 return INVALID_OPERATION;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002101 }
2102
Eric Laurent599c7582015-12-07 18:05:55 -08002103 audioSession->changeActiveCount(-1);
Paul McLean466dc8e2015-04-17 13:15:36 -06002104
2105 // Routing?
2106 mInputRoutes.decRouteActivity(session);
2107
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002108 if (audioSession->activeCount() == 0) {
Eric Laurent84332aa2016-01-28 22:19:18 +00002109
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002110 if (inputDesc->isActive()) {
2111 setInputDevice(input, getNewInputDevice(inputDesc), false /* force */);
2112 } else {
2113 // if input maps to a dynamic policy with an activity listener, notify of state change
2114 if ((inputDesc->mPolicyMix != NULL)
2115 && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
2116 mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mDeviceAddress,
2117 MIX_STATE_IDLE);
Eric Laurent84332aa2016-01-28 22:19:18 +00002118 }
Jean-Michel Trivieb6421d2016-03-17 12:32:52 -07002119
2120 // automatically disable the remote submix output when input is stopped if not
2121 // used by a policy mix of type MIX_TYPE_RECORDERS
2122 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
2123 String8 address = String8("");
2124 if (inputDesc->mPolicyMix == NULL) {
2125 address = String8("0");
2126 } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
2127 address = inputDesc->mPolicyMix->mDeviceAddress;
2128 }
2129 if (address != "") {
2130 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2131 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2132 address, "remote-submix");
2133 }
Eric Laurent84332aa2016-01-28 22:19:18 +00002134 }
Eric Laurent84332aa2016-01-28 22:19:18 +00002135
Eric Laurentf7c50102016-09-30 15:19:43 -07002136 audio_devices_t device = inputDesc->mDevice;
Eric Laurentfb66dd92016-01-28 18:32:03 -08002137 resetInputDevice(input);
Eric Laurent84332aa2016-01-28 22:19:18 +00002138
Eric Laurentf7c50102016-09-30 15:19:43 -07002139 // indicate inactive capture to sound trigger service if stopping capture from a mic on
2140 // primary HW module
2141 audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
2142 if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
2143 mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0) {
Eric Laurentfb66dd92016-01-28 18:32:03 -08002144 SoundTrigger::setCaptureState(false);
2145 }
2146 inputDesc->clearPreemptedSessions();
Eric Laurent84332aa2016-01-28 22:19:18 +00002147 }
Eric Laurente552edb2014-03-10 17:42:56 -07002148 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002149 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07002150}
2151
Eric Laurent4dc68062014-07-28 17:26:49 -07002152void AudioPolicyManager::releaseInput(audio_io_handle_t input,
2153 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07002154{
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08002155
Eric Laurente552edb2014-03-10 17:42:56 -07002156 ALOGV("releaseInput() %d", input);
2157 ssize_t index = mInputs.indexOfKey(input);
2158 if (index < 0) {
2159 ALOGW("releaseInput() releasing unknown input %d", input);
2160 return;
2161 }
Paul McLean466dc8e2015-04-17 13:15:36 -06002162
2163 // Routing
2164 mInputRoutes.removeRoute(session);
2165
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002166 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
2167 ALOG_ASSERT(inputDesc != 0);
Eric Laurent4dc68062014-07-28 17:26:49 -07002168
Eric Laurent599c7582015-12-07 18:05:55 -08002169 sp<AudioSession> audioSession = inputDesc->getAudioSession(session);
vivek mehta587b8df2017-01-31 14:58:44 -08002170 if (audioSession == 0) {
Eric Laurent4dc68062014-07-28 17:26:49 -07002171 ALOGW("releaseInput() unknown session %d on input %d", session, input);
2172 return;
2173 }
Eric Laurent599c7582015-12-07 18:05:55 -08002174
2175 if (audioSession->openCount() == 0) {
2176 ALOGW("releaseInput() invalid open count %d on session %d",
2177 audioSession->openCount(), session);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002178 return;
2179 }
Eric Laurent599c7582015-12-07 18:05:55 -08002180
2181 if (audioSession->changeOpenCount(-1) == 0) {
2182 inputDesc->removeAudioSession(session);
2183 }
2184
Jean-Michel Trivi65bfe912015-12-04 15:56:47 -08002185 if (inputDesc->getOpenRefCount() > 0) {
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002186 ALOGV("releaseInput() exit > 0");
2187 return;
2188 }
2189
Eric Laurent05b90f82014-08-27 15:32:29 -07002190 closeInput(input);
Eric Laurentb52c1522014-05-20 11:27:36 -07002191 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07002192 ALOGV("releaseInput() exit");
2193}
2194
Eric Laurentd4692962014-05-05 18:13:44 -07002195void AudioPolicyManager::closeAllInputs() {
Eric Laurent05b90f82014-08-27 15:32:29 -07002196 bool patchRemoved = false;
2197
Eric Laurentd4692962014-05-05 18:13:44 -07002198 for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
Eric Laurent05b90f82014-08-27 15:32:29 -07002199 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(input_index);
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08002200 ssize_t patch_index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
Eric Laurent05b90f82014-08-27 15:32:29 -07002201 if (patch_index >= 0) {
2202 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patch_index);
Glenn Kastenfcddb0b2016-07-08 17:19:25 -07002203 (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent05b90f82014-08-27 15:32:29 -07002204 mAudioPatches.removeItemsAt(patch_index);
2205 patchRemoved = true;
2206 }
Eric Laurentd4692962014-05-05 18:13:44 -07002207 mpClientInterface->closeInput(mInputs.keyAt(input_index));
2208 }
2209 mInputs.clear();
Chris Thornton52785f32016-02-09 17:28:49 -08002210 SoundTrigger::setCaptureState(false);
Eric Laurent6a94d692014-05-20 11:18:06 -07002211 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07002212
2213 if (patchRemoved) {
2214 mpClientInterface->onAudioPatchListUpdate();
2215 }
Eric Laurentd4692962014-05-05 18:13:44 -07002216}
2217
Eric Laurente0720872014-03-11 09:30:41 -07002218void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07002219 int indexMin,
2220 int indexMax)
2221{
2222 ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
François Gaffied1ab2bd2015-12-02 18:20:06 +01002223 mVolumeCurves->initStreamVolume(stream, indexMin, indexMax);
Eric Laurent28d09f02016-03-08 10:43:05 -08002224
2225 // initialize other private stream volumes which follow this one
Eric Laurent794fde22016-03-11 09:50:45 -08002226 for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2227 if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08002228 continue;
2229 }
2230 mVolumeCurves->initStreamVolume((audio_stream_type_t)curStream, indexMin, indexMax);
Eric Laurent223fd5c2014-11-11 13:43:36 -08002231 }
Eric Laurente552edb2014-03-10 17:42:56 -07002232}
2233
Eric Laurente0720872014-03-11 09:30:41 -07002234status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
François Gaffie53615e22015-03-19 09:24:12 +01002235 int index,
2236 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07002237{
2238
François Gaffied1ab2bd2015-12-02 18:20:06 +01002239 if ((index < mVolumeCurves->getVolumeIndexMin(stream)) ||
2240 (index > mVolumeCurves->getVolumeIndexMax(stream))) {
Eric Laurente552edb2014-03-10 17:42:56 -07002241 return BAD_VALUE;
2242 }
2243 if (!audio_is_output_device(device)) {
2244 return BAD_VALUE;
2245 }
2246
2247 // Force max volume if stream cannot be muted
François Gaffied1ab2bd2015-12-02 18:20:06 +01002248 if (!mVolumeCurves->canBeMuted(stream)) index = mVolumeCurves->getVolumeIndexMax(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07002249
Eric Laurent1fd372e2016-04-06 14:23:53 -07002250 ALOGV("setStreamVolumeIndex() stream %d, device %08x, index %d",
Eric Laurente552edb2014-03-10 17:42:56 -07002251 stream, device, index);
2252
Eric Laurent28d09f02016-03-08 10:43:05 -08002253 // update other private stream volumes which follow this one
Eric Laurent794fde22016-03-11 09:50:45 -08002254 for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2255 if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08002256 continue;
2257 }
2258 mVolumeCurves->addCurrentVolumeIndex((audio_stream_type_t)curStream, device, index);
2259 }
Eric Laurente552edb2014-03-10 17:42:56 -07002260
Eric Laurent1fd372e2016-04-06 14:23:53 -07002261 // update volume on all outputs and streams matching the following:
2262 // - The requested stream (or a stream matching for volume control) is active on the output
2263 // - The device (or devices) selected by the strategy corresponding to this stream includes
2264 // the requested device
2265 // - For non default requested device, currently selected device on the output is either the
2266 // requested device or one of the devices selected by the strategy
Eric Laurent5a2b6292016-04-14 18:05:57 -07002267 // - For default requested device (AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME), apply volume only if
2268 // no specific device volume value exists for currently selected device.
Eric Laurente552edb2014-03-10 17:42:56 -07002269 status_t status = NO_ERROR;
2270 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002271 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
2272 audio_devices_t curDevice = Volume::getDeviceForVolume(desc->device());
Eric Laurent794fde22016-03-11 09:50:45 -08002273 for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
2274 if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08002275 continue;
Eric Laurente552edb2014-03-10 17:42:56 -07002276 }
Eric Laurentd3926fe2016-04-15 18:10:07 -07002277 if (!(desc->isStreamActive((audio_stream_type_t)curStream) ||
2278 (isInCall() && (curStream == AUDIO_STREAM_VOICE_CALL)))) {
Eric Laurent1fd372e2016-04-06 14:23:53 -07002279 continue;
2280 }
Eric Laurent794fde22016-03-11 09:50:45 -08002281 routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
Jean-Michel Trivib7fdce62017-06-27 19:38:42 -07002282 audio_devices_t curStreamDevice = Volume::getDeviceForVolume(getDeviceForStrategy(
2283 curStrategy, false /*fromCache*/));
Eric Laurente76f29c2016-09-14 17:17:53 -07002284 if ((device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) &&
2285 ((curStreamDevice & device) == 0)) {
Eric Laurent1fd372e2016-04-06 14:23:53 -07002286 continue;
2287 }
Eric Laurente76f29c2016-09-14 17:17:53 -07002288 bool applyVolume;
Eric Laurent5a2b6292016-04-14 18:05:57 -07002289 if (device != AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
Eric Laurent1fd372e2016-04-06 14:23:53 -07002290 curStreamDevice |= device;
Eric Laurente76f29c2016-09-14 17:17:53 -07002291 applyVolume = (curDevice & curStreamDevice) != 0;
2292 } else {
2293 applyVolume = !mVolumeCurves->hasVolumeIndexForDevice(
Jean-Michel Trivib7fdce62017-06-27 19:38:42 -07002294 stream, curStreamDevice);
Eric Laurent1fd372e2016-04-06 14:23:53 -07002295 }
Eric Laurent28d09f02016-03-08 10:43:05 -08002296
Eric Laurente76f29c2016-09-14 17:17:53 -07002297 if (applyVolume) {
Eric Laurentdc462862016-07-19 12:29:53 -07002298 //FIXME: workaround for truncated touch sounds
2299 // delayed volume change for system stream to be removed when the problem is
2300 // handled by system UI
Eric Laurent28d09f02016-03-08 10:43:05 -08002301 status_t volStatus =
Eric Laurentdc462862016-07-19 12:29:53 -07002302 checkAndSetVolume((audio_stream_type_t)curStream, index, desc, curDevice,
2303 (stream == AUDIO_STREAM_SYSTEM) ? TOUCH_SOUND_FIXED_DELAY_MS : 0);
Eric Laurent28d09f02016-03-08 10:43:05 -08002304 if (volStatus != NO_ERROR) {
2305 status = volStatus;
2306 }
2307 }
Eric Laurent223fd5c2014-11-11 13:43:36 -08002308 }
Eric Laurente552edb2014-03-10 17:42:56 -07002309 }
2310 return status;
2311}
2312
Eric Laurente0720872014-03-11 09:30:41 -07002313status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07002314 int *index,
2315 audio_devices_t device)
2316{
2317 if (index == NULL) {
2318 return BAD_VALUE;
2319 }
2320 if (!audio_is_output_device(device)) {
2321 return BAD_VALUE;
2322 }
Eric Laurent5a2b6292016-04-14 18:05:57 -07002323 // if device is AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME, return volume for device corresponding to
Eric Laurente552edb2014-03-10 17:42:56 -07002324 // the strategy the stream belongs to.
Eric Laurent5a2b6292016-04-14 18:05:57 -07002325 if (device == AUDIO_DEVICE_OUT_DEFAULT_FOR_VOLUME) {
Eric Laurente552edb2014-03-10 17:42:56 -07002326 device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
2327 }
François Gaffiedfd74092015-03-19 12:10:59 +01002328 device = Volume::getDeviceForVolume(device);
Eric Laurente552edb2014-03-10 17:42:56 -07002329
François Gaffied1ab2bd2015-12-02 18:20:06 +01002330 *index = mVolumeCurves->getVolumeIndex(stream, device);
Eric Laurente552edb2014-03-10 17:42:56 -07002331 ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
2332 return NO_ERROR;
2333}
2334
Eric Laurent36829f92017-04-07 19:04:42 -07002335audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
Eric Laurente552edb2014-03-10 17:42:56 -07002336{
2337 // select one output among several suitable for global effects.
2338 // The priority is as follows:
2339 // 1: An offloaded output. If the effect ends up not being offloadable,
2340 // AudioFlinger will invalidate the track and the offloaded output
2341 // will be closed causing the effect to be moved to a PCM output.
2342 // 2: A deep buffer output
Eric Laurent36829f92017-04-07 19:04:42 -07002343 // 3: The primary output
2344 // 4: the first output in the list
Eric Laurente552edb2014-03-10 17:42:56 -07002345
Eric Laurent3b73df72014-03-11 09:06:29 -07002346 routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
Eric Laurente552edb2014-03-10 17:42:56 -07002347 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
Eric Laurent36829f92017-04-07 19:04:42 -07002348 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
Eric Laurente552edb2014-03-10 17:42:56 -07002349
Eric Laurent36829f92017-04-07 19:04:42 -07002350 if (outputs.size() == 0) {
2351 return AUDIO_IO_HANDLE_NONE;
2352 }
Eric Laurente552edb2014-03-10 17:42:56 -07002353
Eric Laurent36829f92017-04-07 19:04:42 -07002354 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
2355 bool activeOnly = true;
2356
2357 while (output == AUDIO_IO_HANDLE_NONE) {
2358 audio_io_handle_t outputOffloaded = AUDIO_IO_HANDLE_NONE;
2359 audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
2360 audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;
2361
2362 for (size_t i = 0; i < outputs.size(); i++) {
2363 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
2364 if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
2365 continue;
2366 }
2367 ALOGV("selectOutputForMusicEffects activeOnly %d outputs[%zu] flags 0x%08x",
2368 activeOnly, i, desc->mFlags);
2369 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
2370 outputOffloaded = outputs[i];
2371 }
2372 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
2373 outputDeepBuffer = outputs[i];
2374 }
2375 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
2376 outputPrimary = outputs[i];
2377 }
2378 }
2379 if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
2380 output = outputOffloaded;
2381 } else if (outputDeepBuffer != AUDIO_IO_HANDLE_NONE) {
2382 output = outputDeepBuffer;
2383 } else if (outputPrimary != AUDIO_IO_HANDLE_NONE) {
2384 output = outputPrimary;
2385 } else {
2386 output = outputs[0];
2387 }
2388 activeOnly = false;
2389 }
2390
2391 if (output != mMusicEffectOutput) {
2392 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
2393 mMusicEffectOutput = output;
2394 }
2395
2396 ALOGV("selectOutputForMusicEffects selected output %d", output);
Eric Laurente552edb2014-03-10 17:42:56 -07002397 return output;
2398}
2399
Eric Laurent36829f92017-04-07 19:04:42 -07002400audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc __unused)
2401{
2402 return selectOutputForMusicEffects();
2403}
2404
Eric Laurente0720872014-03-11 09:30:41 -07002405status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
Eric Laurente552edb2014-03-10 17:42:56 -07002406 audio_io_handle_t io,
2407 uint32_t strategy,
2408 int session,
2409 int id)
2410{
2411 ssize_t index = mOutputs.indexOfKey(io);
2412 if (index < 0) {
2413 index = mInputs.indexOfKey(io);
2414 if (index < 0) {
2415 ALOGW("registerEffect() unknown io %d", io);
2416 return INVALID_OPERATION;
2417 }
2418 }
François Gaffie45ed3b02015-03-19 10:35:14 +01002419 return mEffects.registerEffect(desc, io, strategy, session, id);
Eric Laurente552edb2014-03-10 17:42:56 -07002420}
2421
Eric Laurentc75307b2015-03-17 15:29:32 -07002422bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
2423{
Eric Laurent28d09f02016-03-08 10:43:05 -08002424 bool active = false;
Eric Laurent794fde22016-03-11 09:50:45 -08002425 for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT && !active; curStream++) {
2426 if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08002427 continue;
2428 }
2429 active = mOutputs.isStreamActive((audio_stream_type_t)curStream, inPastMs);
2430 }
Eric Laurent28d09f02016-03-08 10:43:05 -08002431 return active;
Eric Laurentc75307b2015-03-17 15:29:32 -07002432}
2433
2434bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
2435{
2436 return mOutputs.isStreamActiveRemotely(stream, inPastMs);
2437}
2438
Eric Laurente0720872014-03-11 09:30:41 -07002439bool AudioPolicyManager::isSourceActive(audio_source_t source) const
Eric Laurente552edb2014-03-10 17:42:56 -07002440{
2441 for (size_t i = 0; i < mInputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002442 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
Eric Laurent599c7582015-12-07 18:05:55 -08002443 if (inputDescriptor->isSourceActive(source)) {
Eric Laurente552edb2014-03-10 17:42:56 -07002444 return true;
2445 }
2446 }
2447 return false;
2448}
2449
Eric Laurent275e8e92014-11-30 15:14:47 -08002450// Register a list of custom mixes with their attributes and format.
2451// When a mix is registered, corresponding input and output profiles are
2452// added to the remote submix hw module. The profile contains only the
2453// parameters (sampling rate, format...) specified by the mix.
2454// The corresponding input remote submix device is also connected.
2455//
2456// When a remote submix device is connected, the address is checked to select the
2457// appropriate profile and the corresponding input or output stream is opened.
2458//
2459// When capture starts, getInputForAttr() will:
2460// - 1 look for a mix matching the address passed in attribtutes tags if any
2461// - 2 if none found, getDeviceForInputSource() will:
2462// - 2.1 look for a mix matching the attributes source
2463// - 2.2 if none found, default to device selection by policy rules
2464// At this time, the corresponding output remote submix device is also connected
2465// and active playback use cases can be transferred to this mix if needed when reconnecting
2466// after AudioTracks are invalidated
2467//
2468// When playback starts, getOutputForAttr() will:
2469// - 1 look for a mix matching the address passed in attribtutes tags if any
2470// - 2 if none found, look for a mix matching the attributes usage
2471// - 3 if none found, default to device and output selection by policy rules.
2472
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07002473status_t AudioPolicyManager::registerPolicyMixes(const Vector<AudioMix>& mixes)
Eric Laurent275e8e92014-11-30 15:14:47 -08002474{
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002475 ALOGV("registerPolicyMixes() %zu mix(es)", mixes.size());
2476 status_t res = NO_ERROR;
2477
2478 sp<HwModule> rSubmixModule;
2479 // examine each mix's route type
2480 for (size_t i = 0; i < mixes.size(); i++) {
2481 // we only support MIX_ROUTE_FLAG_LOOP_BACK or MIX_ROUTE_FLAG_RENDER, not the combination
2482 if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_ALL) == MIX_ROUTE_FLAG_ALL) {
2483 res = INVALID_OPERATION;
Eric Laurent275e8e92014-11-30 15:14:47 -08002484 break;
2485 }
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002486 if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
2487 // Loop back through "remote submix"
2488 if (rSubmixModule == 0) {
2489 for (size_t j = 0; i < mHwModules.size(); j++) {
2490 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
2491 && mHwModules[j]->mHandle != 0) {
2492 rSubmixModule = mHwModules[j];
2493 break;
2494 }
2495 }
2496 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002497
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002498 ALOGV("registerPolicyMixes() mix %zu of %zu is LOOP_BACK", i, mixes.size());
Eric Laurent275e8e92014-11-30 15:14:47 -08002499
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002500 if (rSubmixModule == 0) {
2501 ALOGE(" Unable to find audio module for submix, aborting mix %zu registration", i);
2502 res = INVALID_OPERATION;
2503 break;
2504 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002505
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002506 String8 address = mixes[i].mDeviceAddress;
François Gaffie036e1e92015-03-19 10:16:24 +01002507
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002508 if (mPolicyMixes.registerMix(address, mixes[i], 0 /*output desc*/) != NO_ERROR) {
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002509 ALOGE(" Error registering mix %zu for address %s", i, address.string());
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002510 res = INVALID_OPERATION;
2511 break;
2512 }
2513 audio_config_t outputConfig = mixes[i].mFormat;
2514 audio_config_t inputConfig = mixes[i].mFormat;
2515 // NOTE: audio flinger mixer does not support mono output: configure remote submix HAL in
2516 // stereo and let audio flinger do the channel conversion if needed.
2517 outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
2518 inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO;
2519 rSubmixModule->addOutputProfile(address, &outputConfig,
2520 AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address);
2521 rSubmixModule->addInputProfile(address, &inputConfig,
2522 AUDIO_DEVICE_IN_REMOTE_SUBMIX, address);
François Gaffie036e1e92015-03-19 10:16:24 +01002523
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002524 if (mixes[i].mMixType == MIX_TYPE_PLAYERS) {
2525 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
2526 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2527 address.string(), "remote-submix");
2528 } else {
2529 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2530 AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
2531 address.string(), "remote-submix");
2532 }
2533 } else if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002534 String8 address = mixes[i].mDeviceAddress;
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002535 audio_devices_t device = mixes[i].mDeviceType;
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002536 ALOGV(" registerPolicyMixes() mix %zu of %zu is RENDER, dev=0x%X addr=%s",
2537 i, mixes.size(), device, address.string());
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002538
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002539 bool foundOutput = false;
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002540 for (size_t j = 0 ; j < mOutputs.size() ; j++) {
2541 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(j);
2542 sp<AudioPatch> patch = mAudioPatches.valueFor(desc->getPatchHandle());
2543 if ((patch != 0) && (patch->mPatch.num_sinks != 0)
2544 && (patch->mPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE)
2545 && (patch->mPatch.sinks[0].ext.device.type == device)
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002546 && (strncmp(patch->mPatch.sinks[0].ext.device.address, address.string(),
2547 AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0)) {
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002548 if (mPolicyMixes.registerMix(address, mixes[i], desc) != NO_ERROR) {
2549 res = INVALID_OPERATION;
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002550 } else {
2551 foundOutput = true;
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002552 }
2553 break;
2554 }
2555 }
2556
2557 if (res != NO_ERROR) {
2558 ALOGE(" Error registering mix %zu for device 0x%X addr %s",
Jean-Michel Trivi5ac8cd42016-03-24 16:35:36 -07002559 i, device, address.string());
2560 res = INVALID_OPERATION;
2561 break;
2562 } else if (!foundOutput) {
2563 ALOGE(" Output not found for mix %zu for device 0x%X addr %s",
2564 i, device, address.string());
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002565 res = INVALID_OPERATION;
2566 break;
2567 }
Eric Laurentc722f302014-12-10 11:21:49 -08002568 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002569 }
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002570 if (res != NO_ERROR) {
2571 unregisterPolicyMixes(mixes);
2572 }
2573 return res;
Eric Laurent275e8e92014-11-30 15:14:47 -08002574}
2575
2576status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
2577{
Eric Laurent7b279bb2015-12-14 10:18:23 -08002578 ALOGV("unregisterPolicyMixes() num mixes %zu", mixes.size());
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002579 status_t res = NO_ERROR;
2580 sp<HwModule> rSubmixModule;
2581 // examine each mix's route type
Eric Laurent275e8e92014-11-30 15:14:47 -08002582 for (size_t i = 0; i < mixes.size(); i++) {
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002583 if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_LOOP_BACK) == MIX_ROUTE_FLAG_LOOP_BACK) {
François Gaffie036e1e92015-03-19 10:16:24 +01002584
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002585 if (rSubmixModule == 0) {
2586 for (size_t j = 0; i < mHwModules.size(); j++) {
2587 if (strcmp(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, mHwModules[j]->mName) == 0
2588 && mHwModules[j]->mHandle != 0) {
2589 rSubmixModule = mHwModules[j];
2590 break;
2591 }
2592 }
2593 }
2594 if (rSubmixModule == 0) {
2595 res = INVALID_OPERATION;
2596 continue;
2597 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002598
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002599 String8 address = mixes[i].mDeviceAddress;
Eric Laurent275e8e92014-11-30 15:14:47 -08002600
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002601 if (mPolicyMixes.unregisterMix(address) != NO_ERROR) {
2602 res = INVALID_OPERATION;
2603 continue;
2604 }
2605
2606 if (getDeviceConnectionState(AUDIO_DEVICE_IN_REMOTE_SUBMIX, address.string()) ==
2607 AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
2608 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
2609 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2610 address.string(), "remote-submix");
2611 }
2612 if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
2613 AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
2614 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
2615 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
2616 address.string(), "remote-submix");
2617 }
2618 rSubmixModule->removeOutputProfile(address);
2619 rSubmixModule->removeInputProfile(address);
2620
2621 } if ((mixes[i].mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
2622 if (mPolicyMixes.unregisterMix(mixes[i].mDeviceAddress) != NO_ERROR) {
2623 res = INVALID_OPERATION;
2624 continue;
2625 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002626 }
Eric Laurent275e8e92014-11-30 15:14:47 -08002627 }
Jean-Michel Trivi7638ca22016-03-04 17:42:44 -08002628 return res;
Eric Laurent275e8e92014-11-30 15:14:47 -08002629}
2630
Eric Laurente552edb2014-03-10 17:42:56 -07002631
Eric Laurente0720872014-03-11 09:30:41 -07002632status_t AudioPolicyManager::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07002633{
2634 const size_t SIZE = 256;
2635 char buffer[SIZE];
2636 String8 result;
2637
2638 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
2639 result.append(buffer);
2640
Eric Laurent87ffa392015-05-22 10:32:38 -07002641 snprintf(buffer, SIZE, " Primary Output: %d\n",
2642 hasPrimaryOutput() ? mPrimaryOutput->mIoHandle : AUDIO_IO_HANDLE_NONE);
Eric Laurente552edb2014-03-10 17:42:56 -07002643 result.append(buffer);
Mikhail Naganov0d6a0332016-04-19 17:12:38 -07002644 std::string stateLiteral;
2645 AudioModeConverter::toString(mEngine->getPhoneState(), stateLiteral);
2646 snprintf(buffer, SIZE, " Phone state: %s\n", stateLiteral.c_str());
Eric Laurente552edb2014-03-10 17:42:56 -07002647 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07002648 snprintf(buffer, SIZE, " Force use for communications %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01002649 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION));
Eric Laurente552edb2014-03-10 17:42:56 -07002650 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002651 snprintf(buffer, SIZE, " Force use for media %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA));
Eric Laurente552edb2014-03-10 17:42:56 -07002652 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002653 snprintf(buffer, SIZE, " Force use for record %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD));
Eric Laurente552edb2014-03-10 17:42:56 -07002654 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002655 snprintf(buffer, SIZE, " Force use for dock %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK));
Eric Laurente552edb2014-03-10 17:42:56 -07002656 result.append(buffer);
François Gaffie2110e042015-03-24 08:41:51 +01002657 snprintf(buffer, SIZE, " Force use for system %d\n", mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM));
Eric Laurente552edb2014-03-10 17:42:56 -07002658 result.append(buffer);
Jungshik Jang7b24ee32014-07-15 19:38:42 +09002659 snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
François Gaffie2110e042015-03-24 08:41:51 +01002660 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
Jungshik Jang7b24ee32014-07-15 19:38:42 +09002661 result.append(buffer);
Phil Burk09bc4612016-02-24 15:58:15 -08002662 snprintf(buffer, SIZE, " Force use for encoded surround output %d\n",
2663 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND));
2664 result.append(buffer);
Eric Laurent9459fb02015-08-12 18:36:32 -07002665 snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
2666 result.append(buffer);
Andy Hung2ddee192015-12-18 17:34:44 -08002667 snprintf(buffer, SIZE, " Master mono: %s\n", mMasterMono ? "on" : "off");
2668 result.append(buffer);
Eric Laurent9459fb02015-08-12 18:36:32 -07002669
François Gaffie2110e042015-03-24 08:41:51 +01002670 write(fd, result.string(), result.size());
Eric Laurente552edb2014-03-10 17:42:56 -07002671
François Gaffie112b0af2015-11-19 16:13:25 +01002672 mAvailableOutputDevices.dump(fd, String8("Available output"));
2673 mAvailableInputDevices.dump(fd, String8("Available input"));
François Gaffie53615e22015-03-19 09:24:12 +01002674 mHwModules.dump(fd);
2675 mOutputs.dump(fd);
2676 mInputs.dump(fd);
François Gaffied1ab2bd2015-12-02 18:20:06 +01002677 mVolumeCurves->dump(fd);
François Gaffie45ed3b02015-03-19 10:35:14 +01002678 mEffects.dump(fd);
François Gaffie53615e22015-03-19 09:24:12 +01002679 mAudioPatches.dump(fd);
Mikhail Naganov44344b02016-12-13 11:21:02 -08002680 mPolicyMixes.dump(fd);
Eric Laurente552edb2014-03-10 17:42:56 -07002681
2682 return NO_ERROR;
2683}
2684
2685// This function checks for the parameters which can be offloaded.
2686// This can be enhanced depending on the capability of the DSP and policy
2687// of the system.
Eric Laurente0720872014-03-11 09:30:41 -07002688bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -07002689{
2690 ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
Eric Laurentd4692962014-05-05 18:13:44 -07002691 " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
Eric Laurente552edb2014-03-10 17:42:56 -07002692 offloadInfo.sample_rate, offloadInfo.channel_mask,
2693 offloadInfo.format,
2694 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
2695 offloadInfo.has_video);
2696
Andy Hung2ddee192015-12-18 17:34:44 -08002697 if (mMasterMono) {
2698 return false; // no offloading if mono is set.
2699 }
2700
Eric Laurente552edb2014-03-10 17:42:56 -07002701 // Check if offload has been disabled
2702 char propValue[PROPERTY_VALUE_MAX];
2703 if (property_get("audio.offload.disable", propValue, "0")) {
2704 if (atoi(propValue) != 0) {
2705 ALOGV("offload disabled by audio.offload.disable=%s", propValue );
2706 return false;
2707 }
2708 }
2709
2710 // Check if stream type is music, then only allow offload as of now.
2711 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
2712 {
2713 ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
2714 return false;
2715 }
2716
2717 //TODO: enable audio offloading with video when ready
Andy Hung08945c42015-05-31 21:36:46 -07002718 const bool allowOffloadWithVideo =
2719 property_get_bool("audio.offload.video", false /* default_value */);
2720 if (offloadInfo.has_video && !allowOffloadWithVideo) {
Eric Laurente552edb2014-03-10 17:42:56 -07002721 ALOGV("isOffloadSupported: has_video == true, returning false");
2722 return false;
2723 }
2724
2725 //If duration is less than minimum value defined in property, return false
2726 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
2727 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
2728 ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
2729 return false;
2730 }
2731 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
2732 ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
2733 return false;
2734 }
2735
2736 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
2737 // creating an offloaded track and tearing it down immediately after start when audioflinger
2738 // detects there is an active non offloadable effect.
2739 // FIXME: We should check the audio session here but we do not have it in this context.
2740 // This may prevent offloading in rare situations where effects are left active by apps
2741 // in the background.
François Gaffie45ed3b02015-03-19 10:35:14 +01002742 if (mEffects.isNonOffloadableEffectEnabled()) {
Eric Laurente552edb2014-03-10 17:42:56 -07002743 return false;
2744 }
2745
2746 // See if there is a profile to support this.
2747 // AUDIO_DEVICE_NONE
Eric Laurent1c333e22014-05-20 10:48:17 -07002748 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Eric Laurente552edb2014-03-10 17:42:56 -07002749 offloadInfo.sample_rate,
2750 offloadInfo.format,
2751 offloadInfo.channel_mask,
2752 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Eric Laurent1c333e22014-05-20 10:48:17 -07002753 ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
2754 return (profile != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07002755}
2756
Eric Laurent6a94d692014-05-20 11:18:06 -07002757status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
2758 audio_port_type_t type,
2759 unsigned int *num_ports,
2760 struct audio_port *ports,
2761 unsigned int *generation)
2762{
2763 if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
2764 generation == NULL) {
2765 return BAD_VALUE;
2766 }
2767 ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
2768 if (ports == NULL) {
2769 *num_ports = 0;
2770 }
2771
2772 size_t portsWritten = 0;
2773 size_t portsMax = *num_ports;
2774 *num_ports = 0;
2775 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
Eric Laurent5a2b6292016-04-14 18:05:57 -07002776 // do not report devices with type AUDIO_DEVICE_IN_STUB or AUDIO_DEVICE_OUT_STUB
2777 // as they are used by stub HALs by convention
Eric Laurent6a94d692014-05-20 11:18:06 -07002778 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent5a2b6292016-04-14 18:05:57 -07002779 for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
2780 if (mAvailableOutputDevices[i]->type() == AUDIO_DEVICE_OUT_STUB) {
2781 continue;
2782 }
2783 if (portsWritten < portsMax) {
2784 mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
2785 }
2786 (*num_ports)++;
Eric Laurent6a94d692014-05-20 11:18:06 -07002787 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002788 }
2789 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent5a2b6292016-04-14 18:05:57 -07002790 for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
2791 if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_STUB) {
2792 continue;
2793 }
2794 if (portsWritten < portsMax) {
2795 mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
2796 }
2797 (*num_ports)++;
Eric Laurent6a94d692014-05-20 11:18:06 -07002798 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002799 }
2800 }
2801 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
2802 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
2803 for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
2804 mInputs[i]->toAudioPort(&ports[portsWritten++]);
2805 }
2806 *num_ports += mInputs.size();
2807 }
2808 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent84c70242014-06-23 08:46:27 -07002809 size_t numOutputs = 0;
2810 for (size_t i = 0; i < mOutputs.size(); i++) {
2811 if (!mOutputs[i]->isDuplicated()) {
2812 numOutputs++;
2813 if (portsWritten < portsMax) {
2814 mOutputs[i]->toAudioPort(&ports[portsWritten++]);
2815 }
2816 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002817 }
Eric Laurent84c70242014-06-23 08:46:27 -07002818 *num_ports += numOutputs;
Eric Laurent6a94d692014-05-20 11:18:06 -07002819 }
2820 }
2821 *generation = curAudioPortGeneration();
Mark Salyzynbeb9e302014-06-18 16:33:15 -07002822 ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
Eric Laurent6a94d692014-05-20 11:18:06 -07002823 return NO_ERROR;
2824}
2825
2826status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
2827{
2828 return NO_ERROR;
2829}
2830
Eric Laurent6a94d692014-05-20 11:18:06 -07002831status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
2832 audio_patch_handle_t *handle,
2833 uid_t uid)
2834{
2835 ALOGV("createAudioPatch()");
2836
2837 if (handle == NULL || patch == NULL) {
2838 return BAD_VALUE;
2839 }
2840 ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
2841
Eric Laurent874c42872014-08-08 15:13:39 -07002842 if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2843 patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2844 return BAD_VALUE;
2845 }
2846 // only one source per audio patch supported for now
2847 if (patch->num_sources > 1) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002848 return INVALID_OPERATION;
2849 }
Eric Laurent874c42872014-08-08 15:13:39 -07002850
2851 if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002852 return INVALID_OPERATION;
2853 }
Eric Laurent874c42872014-08-08 15:13:39 -07002854 for (size_t i = 0; i < patch->num_sinks; i++) {
2855 if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2856 return INVALID_OPERATION;
2857 }
2858 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002859
2860 sp<AudioPatch> patchDesc;
2861 ssize_t index = mAudioPatches.indexOfKey(*handle);
2862
Eric Laurent6a94d692014-05-20 11:18:06 -07002863 ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
2864 patch->sources[0].role,
2865 patch->sources[0].type);
Eric Laurent874c42872014-08-08 15:13:39 -07002866#if LOG_NDEBUG == 0
2867 for (size_t i = 0; i < patch->num_sinks; i++) {
Eric Laurent7b279bb2015-12-14 10:18:23 -08002868 ALOGV("createAudioPatch sink %zu: id %d role %d type %d", i, patch->sinks[i].id,
Eric Laurent874c42872014-08-08 15:13:39 -07002869 patch->sinks[i].role,
2870 patch->sinks[i].type);
2871 }
2872#endif
Eric Laurent6a94d692014-05-20 11:18:06 -07002873
2874 if (index >= 0) {
2875 patchDesc = mAudioPatches.valueAt(index);
2876 ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2877 mUidCached, patchDesc->mUid, uid);
2878 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2879 return INVALID_OPERATION;
2880 }
2881 } else {
Glenn Kastena13cde92016-03-28 15:26:02 -07002882 *handle = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent6a94d692014-05-20 11:18:06 -07002883 }
2884
2885 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurentc75307b2015-03-17 15:29:32 -07002886 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002887 if (outputDesc == NULL) {
2888 ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
2889 return BAD_VALUE;
2890 }
Eric Laurent84c70242014-06-23 08:46:27 -07002891 ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
2892 outputDesc->mIoHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002893 if (patchDesc != 0) {
2894 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
2895 ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
2896 patchDesc->mPatch.sources[0].id, patch->sources[0].id);
2897 return BAD_VALUE;
2898 }
2899 }
Eric Laurent874c42872014-08-08 15:13:39 -07002900 DeviceVector devices;
2901 for (size_t i = 0; i < patch->num_sinks; i++) {
2902 // Only support mix to devices connection
2903 // TODO add support for mix to mix connection
2904 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2905 ALOGV("createAudioPatch() source mix but sink is not a device");
2906 return INVALID_OPERATION;
2907 }
2908 sp<DeviceDescriptor> devDesc =
2909 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2910 if (devDesc == 0) {
2911 ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2912 return BAD_VALUE;
2913 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002914
François Gaffie53615e22015-03-19 09:24:12 +01002915 if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002916 devDesc->mAddress,
Eric Laurent874c42872014-08-08 15:13:39 -07002917 patch->sources[0].sample_rate,
François Gaffie53615e22015-03-19 09:24:12 +01002918 NULL, // updatedSamplingRate
2919 patch->sources[0].format,
Andy Hungf129b032015-04-07 13:45:50 -07002920 NULL, // updatedFormat
François Gaffie53615e22015-03-19 09:24:12 +01002921 patch->sources[0].channel_mask,
Andy Hungf129b032015-04-07 13:45:50 -07002922 NULL, // updatedChannelMask
François Gaffie53615e22015-03-19 09:24:12 +01002923 AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
Andy Hungf129b032015-04-07 13:45:50 -07002924 ALOGV("createAudioPatch() profile not supported for device %08x",
2925 devDesc->type());
Eric Laurent874c42872014-08-08 15:13:39 -07002926 return INVALID_OPERATION;
2927 }
2928 devices.add(devDesc);
2929 }
2930 if (devices.size() == 0) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002931 return INVALID_OPERATION;
2932 }
Eric Laurent874c42872014-08-08 15:13:39 -07002933
Eric Laurent6a94d692014-05-20 11:18:06 -07002934 // TODO: reconfigure output format and channels here
2935 ALOGV("createAudioPatch() setting device %08x on output %d",
Eric Laurent874c42872014-08-08 15:13:39 -07002936 devices.types(), outputDesc->mIoHandle);
Eric Laurentc75307b2015-03-17 15:29:32 -07002937 setOutputDevice(outputDesc, devices.types(), true, 0, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002938 index = mAudioPatches.indexOfKey(*handle);
2939 if (index >= 0) {
2940 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2941 ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
2942 }
2943 patchDesc = mAudioPatches.valueAt(index);
2944 patchDesc->mUid = uid;
2945 ALOGV("createAudioPatch() success");
2946 } else {
2947 ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
2948 return INVALID_OPERATION;
2949 }
2950 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2951 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
2952 // input device to input mix connection
Eric Laurent874c42872014-08-08 15:13:39 -07002953 // only one sink supported when connecting an input device to a mix
2954 if (patch->num_sinks > 1) {
2955 return INVALID_OPERATION;
2956 }
François Gaffie53615e22015-03-19 09:24:12 +01002957 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002958 if (inputDesc == NULL) {
2959 return BAD_VALUE;
2960 }
2961 if (patchDesc != 0) {
2962 if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
2963 return BAD_VALUE;
2964 }
2965 }
2966 sp<DeviceDescriptor> devDesc =
2967 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
2968 if (devDesc == 0) {
2969 return BAD_VALUE;
2970 }
2971
François Gaffie53615e22015-03-19 09:24:12 +01002972 if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
Eric Laurent275e8e92014-11-30 15:14:47 -08002973 devDesc->mAddress,
2974 patch->sinks[0].sample_rate,
2975 NULL, /*updatedSampleRate*/
2976 patch->sinks[0].format,
Andy Hungf129b032015-04-07 13:45:50 -07002977 NULL, /*updatedFormat*/
Eric Laurent275e8e92014-11-30 15:14:47 -08002978 patch->sinks[0].channel_mask,
Andy Hungf129b032015-04-07 13:45:50 -07002979 NULL, /*updatedChannelMask*/
Eric Laurent275e8e92014-11-30 15:14:47 -08002980 // FIXME for the parameter type,
2981 // and the NONE
2982 (audio_output_flags_t)
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002983 AUDIO_INPUT_FLAG_NONE)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002984 return INVALID_OPERATION;
2985 }
2986 // TODO: reconfigure output format and channels here
2987 ALOGV("createAudioPatch() setting device %08x on output %d",
François Gaffie53615e22015-03-19 09:24:12 +01002988 devDesc->type(), inputDesc->mIoHandle);
2989 setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002990 index = mAudioPatches.indexOfKey(*handle);
2991 if (index >= 0) {
2992 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2993 ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
2994 }
2995 patchDesc = mAudioPatches.valueAt(index);
2996 patchDesc->mUid = uid;
2997 ALOGV("createAudioPatch() success");
2998 } else {
2999 ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
3000 return INVALID_OPERATION;
3001 }
3002 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
3003 // device to device connection
3004 if (patchDesc != 0) {
Eric Laurent874c42872014-08-08 15:13:39 -07003005 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003006 return BAD_VALUE;
3007 }
3008 }
Eric Laurent6a94d692014-05-20 11:18:06 -07003009 sp<DeviceDescriptor> srcDeviceDesc =
3010 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
Eric Laurent58f8eb72014-09-12 16:19:41 -07003011 if (srcDeviceDesc == 0) {
3012 return BAD_VALUE;
3013 }
Eric Laurent874c42872014-08-08 15:13:39 -07003014
Eric Laurent6a94d692014-05-20 11:18:06 -07003015 //update source and sink with our own data as the data passed in the patch may
3016 // be incomplete.
3017 struct audio_patch newPatch = *patch;
3018 srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
Eric Laurent6a94d692014-05-20 11:18:06 -07003019
Eric Laurent874c42872014-08-08 15:13:39 -07003020 for (size_t i = 0; i < patch->num_sinks; i++) {
3021 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
3022 ALOGV("createAudioPatch() source device but one sink is not a device");
3023 return INVALID_OPERATION;
3024 }
3025
3026 sp<DeviceDescriptor> sinkDeviceDesc =
3027 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
3028 if (sinkDeviceDesc == 0) {
3029 return BAD_VALUE;
3030 }
3031 sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
3032
Eric Laurent3bcf8592015-04-03 12:13:24 -07003033 // create a software bridge in PatchPanel if:
3034 // - source and sink devices are on differnt HW modules OR
3035 // - audio HAL version is < 3.0
Eric Laurentfb66dd92016-01-28 18:32:03 -08003036 if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
Mikhail Naganov9ee05402016-10-13 15:58:17 -07003037 (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
Eric Laurent3bcf8592015-04-03 12:13:24 -07003038 // support only one sink device for now to simplify output selection logic
Eric Laurent874c42872014-08-08 15:13:39 -07003039 if (patch->num_sinks > 1) {
Eric Laurent83b88082014-06-20 18:31:16 -07003040 return INVALID_OPERATION;
3041 }
Eric Laurent874c42872014-08-08 15:13:39 -07003042 SortedVector<audio_io_handle_t> outputs =
François Gaffie53615e22015-03-19 09:24:12 +01003043 getOutputsForDevice(sinkDeviceDesc->type(), mOutputs);
Eric Laurent874c42872014-08-08 15:13:39 -07003044 // if the sink device is reachable via an opened output stream, request to go via
3045 // this output stream by adding a second source to the patch description
Eric Laurent8838a382014-09-08 16:44:28 -07003046 audio_io_handle_t output = selectOutput(outputs,
3047 AUDIO_OUTPUT_FLAG_NONE,
3048 AUDIO_FORMAT_INVALID);
Eric Laurent874c42872014-08-08 15:13:39 -07003049 if (output != AUDIO_IO_HANDLE_NONE) {
3050 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3051 if (outputDesc->isDuplicated()) {
3052 return INVALID_OPERATION;
3053 }
3054 outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
Eric Laurent3bcf8592015-04-03 12:13:24 -07003055 newPatch.sources[1].ext.mix.usecase.stream = AUDIO_STREAM_PATCH;
Eric Laurent874c42872014-08-08 15:13:39 -07003056 newPatch.num_sources = 2;
3057 }
Eric Laurent83b88082014-06-20 18:31:16 -07003058 }
Eric Laurent6a94d692014-05-20 11:18:06 -07003059 }
3060 // TODO: check from routing capabilities in config file and other conflicting patches
3061
3062 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3063 if (index >= 0) {
3064 afPatchHandle = patchDesc->mAfPatchHandle;
3065 }
3066
3067 status_t status = mpClientInterface->createAudioPatch(&newPatch,
3068 &afPatchHandle,
3069 0);
3070 ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
3071 status, afPatchHandle);
3072 if (status == NO_ERROR) {
3073 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01003074 patchDesc = new AudioPatch(&newPatch, uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07003075 addAudioPatch(patchDesc->mHandle, patchDesc);
3076 } else {
3077 patchDesc->mPatch = newPatch;
3078 }
3079 patchDesc->mAfPatchHandle = afPatchHandle;
3080 *handle = patchDesc->mHandle;
3081 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07003082 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07003083 } else {
3084 ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
3085 status);
3086 return INVALID_OPERATION;
3087 }
3088 } else {
3089 return BAD_VALUE;
3090 }
3091 } else {
3092 return BAD_VALUE;
3093 }
3094 return NO_ERROR;
3095}
3096
3097status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
3098 uid_t uid)
3099{
3100 ALOGV("releaseAudioPatch() patch %d", handle);
3101
3102 ssize_t index = mAudioPatches.indexOfKey(handle);
3103
3104 if (index < 0) {
3105 return BAD_VALUE;
3106 }
3107 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3108 ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
3109 mUidCached, patchDesc->mUid, uid);
3110 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
3111 return INVALID_OPERATION;
3112 }
3113
3114 struct audio_patch *patch = &patchDesc->mPatch;
3115 patchDesc->mUid = mUidCached;
3116 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003117 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07003118 if (outputDesc == NULL) {
3119 ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
3120 return BAD_VALUE;
3121 }
3122
Eric Laurentc75307b2015-03-17 15:29:32 -07003123 setOutputDevice(outputDesc,
3124 getNewOutputDevice(outputDesc, true /*fromCache*/),
Eric Laurent6a94d692014-05-20 11:18:06 -07003125 true,
3126 0,
3127 NULL);
3128 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
3129 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
François Gaffie53615e22015-03-19 09:24:12 +01003130 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07003131 if (inputDesc == NULL) {
3132 ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
3133 return BAD_VALUE;
3134 }
3135 setInputDevice(inputDesc->mIoHandle,
Eric Laurentfb66dd92016-01-28 18:32:03 -08003136 getNewInputDevice(inputDesc),
Eric Laurent6a94d692014-05-20 11:18:06 -07003137 true,
3138 NULL);
3139 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003140 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3141 ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
3142 status, patchDesc->mAfPatchHandle);
3143 removeAudioPatch(patchDesc->mHandle);
3144 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07003145 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07003146 } else {
3147 return BAD_VALUE;
3148 }
3149 } else {
3150 return BAD_VALUE;
3151 }
3152 return NO_ERROR;
3153}
3154
3155status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
3156 struct audio_patch *patches,
3157 unsigned int *generation)
3158{
François Gaffie53615e22015-03-19 09:24:12 +01003159 if (generation == NULL) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003160 return BAD_VALUE;
3161 }
Eric Laurent6a94d692014-05-20 11:18:06 -07003162 *generation = curAudioPortGeneration();
François Gaffie53615e22015-03-19 09:24:12 +01003163 return mAudioPatches.listAudioPatches(num_patches, patches);
Eric Laurent6a94d692014-05-20 11:18:06 -07003164}
3165
Eric Laurente1715a42014-05-20 11:30:42 -07003166status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
Eric Laurent6a94d692014-05-20 11:18:06 -07003167{
Eric Laurente1715a42014-05-20 11:30:42 -07003168 ALOGV("setAudioPortConfig()");
3169
3170 if (config == NULL) {
3171 return BAD_VALUE;
3172 }
3173 ALOGV("setAudioPortConfig() on port handle %d", config->id);
3174 // Only support gain configuration for now
Eric Laurenta121f902014-06-03 13:32:54 -07003175 if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
3176 return INVALID_OPERATION;
Eric Laurente1715a42014-05-20 11:30:42 -07003177 }
3178
Eric Laurenta121f902014-06-03 13:32:54 -07003179 sp<AudioPortConfig> audioPortConfig;
Eric Laurente1715a42014-05-20 11:30:42 -07003180 if (config->type == AUDIO_PORT_TYPE_MIX) {
3181 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003182 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.getOutputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07003183 if (outputDesc == NULL) {
3184 return BAD_VALUE;
3185 }
Eric Laurent84c70242014-06-23 08:46:27 -07003186 ALOG_ASSERT(!outputDesc->isDuplicated(),
3187 "setAudioPortConfig() called on duplicated output %d",
3188 outputDesc->mIoHandle);
Eric Laurenta121f902014-06-03 13:32:54 -07003189 audioPortConfig = outputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07003190 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
François Gaffie53615e22015-03-19 09:24:12 +01003191 sp<AudioInputDescriptor> inputDesc = mInputs.getInputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07003192 if (inputDesc == NULL) {
3193 return BAD_VALUE;
3194 }
Eric Laurenta121f902014-06-03 13:32:54 -07003195 audioPortConfig = inputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07003196 } else {
3197 return BAD_VALUE;
3198 }
3199 } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
3200 sp<DeviceDescriptor> deviceDesc;
3201 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
3202 deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
3203 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
3204 deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
3205 } else {
3206 return BAD_VALUE;
3207 }
3208 if (deviceDesc == NULL) {
3209 return BAD_VALUE;
3210 }
Eric Laurenta121f902014-06-03 13:32:54 -07003211 audioPortConfig = deviceDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07003212 } else {
3213 return BAD_VALUE;
3214 }
3215
Eric Laurenta121f902014-06-03 13:32:54 -07003216 struct audio_port_config backupConfig;
3217 status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
3218 if (status == NO_ERROR) {
3219 struct audio_port_config newConfig;
3220 audioPortConfig->toAudioPortConfig(&newConfig, config);
3221 status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
Eric Laurente1715a42014-05-20 11:30:42 -07003222 }
Eric Laurenta121f902014-06-03 13:32:54 -07003223 if (status != NO_ERROR) {
3224 audioPortConfig->applyAudioPortConfig(&backupConfig);
Eric Laurente1715a42014-05-20 11:30:42 -07003225 }
Eric Laurente1715a42014-05-20 11:30:42 -07003226
3227 return status;
Eric Laurent6a94d692014-05-20 11:18:06 -07003228}
3229
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003230void AudioPolicyManager::releaseResourcesForUid(uid_t uid)
3231{
Eric Laurentd60560a2015-04-10 11:31:20 -07003232 clearAudioSources(uid);
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003233 clearAudioPatches(uid);
3234 clearSessionRoutes(uid);
3235}
3236
Eric Laurent6a94d692014-05-20 11:18:06 -07003237void AudioPolicyManager::clearAudioPatches(uid_t uid)
3238{
Eric Laurent0add0fd2014-12-04 18:58:14 -08003239 for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003240 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
3241 if (patchDesc->mUid == uid) {
Eric Laurent0add0fd2014-12-04 18:58:14 -08003242 releaseAudioPatch(mAudioPatches.keyAt(i), uid);
Eric Laurent6a94d692014-05-20 11:18:06 -07003243 }
3244 }
3245}
3246
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003247void AudioPolicyManager::checkStrategyRoute(routing_strategy strategy,
3248 audio_io_handle_t ouptutToSkip)
3249{
3250 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
3251 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
3252 for (size_t j = 0; j < mOutputs.size(); j++) {
3253 if (mOutputs.keyAt(j) == ouptutToSkip) {
3254 continue;
3255 }
3256 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(j);
3257 if (!isStrategyActive(outputDesc, (routing_strategy)strategy)) {
3258 continue;
3259 }
3260 // If the default device for this strategy is on another output mix,
3261 // invalidate all tracks in this strategy to force re connection.
3262 // Otherwise select new device on the output mix.
3263 if (outputs.indexOf(mOutputs.keyAt(j)) < 0) {
Eric Laurent794fde22016-03-11 09:50:45 -08003264 for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003265 if (getStrategy((audio_stream_type_t)stream) == strategy) {
3266 mpClientInterface->invalidateStream((audio_stream_type_t)stream);
3267 }
3268 }
3269 } else {
3270 audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
3271 setOutputDevice(outputDesc, newDevice, false);
3272 }
3273 }
3274}
3275
3276void AudioPolicyManager::clearSessionRoutes(uid_t uid)
3277{
3278 // remove output routes associated with this uid
3279 SortedVector<routing_strategy> affectedStrategies;
3280 for (ssize_t i = (ssize_t)mOutputRoutes.size() - 1; i >= 0; i--) {
3281 sp<SessionRoute> route = mOutputRoutes.valueAt(i);
3282 if (route->mUid == uid) {
3283 mOutputRoutes.removeItemsAt(i);
3284 if (route->mDeviceDescriptor != 0) {
3285 affectedStrategies.add(getStrategy(route->mStreamType));
3286 }
3287 }
3288 }
3289 // reroute outputs if necessary
3290 for (size_t i = 0; i < affectedStrategies.size(); i++) {
3291 checkStrategyRoute(affectedStrategies[i], AUDIO_IO_HANDLE_NONE);
3292 }
3293
3294 // remove input routes associated with this uid
3295 SortedVector<audio_source_t> affectedSources;
3296 for (ssize_t i = (ssize_t)mInputRoutes.size() - 1; i >= 0; i--) {
3297 sp<SessionRoute> route = mInputRoutes.valueAt(i);
3298 if (route->mUid == uid) {
3299 mInputRoutes.removeItemsAt(i);
3300 if (route->mDeviceDescriptor != 0) {
3301 affectedSources.add(route->mSource);
3302 }
3303 }
3304 }
3305 // reroute inputs if necessary
3306 SortedVector<audio_io_handle_t> inputsToClose;
3307 for (size_t i = 0; i < mInputs.size(); i++) {
3308 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(i);
Eric Laurent599c7582015-12-07 18:05:55 -08003309 if (affectedSources.indexOf(inputDesc->inputSource()) >= 0) {
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003310 inputsToClose.add(inputDesc->mIoHandle);
3311 }
3312 }
3313 for (size_t i = 0; i < inputsToClose.size(); i++) {
3314 closeInput(inputsToClose[i]);
3315 }
3316}
3317
Eric Laurentd60560a2015-04-10 11:31:20 -07003318void AudioPolicyManager::clearAudioSources(uid_t uid)
3319{
3320 for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--) {
3321 sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3322 if (sourceDesc->mUid == uid) {
3323 stopAudioSource(mAudioSources.keyAt(i));
3324 }
3325 }
3326}
Eric Laurent8c7e6da2015-04-21 17:37:00 -07003327
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07003328status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
3329 audio_io_handle_t *ioHandle,
3330 audio_devices_t *device)
3331{
Glenn Kastenf0c6d7d2016-02-26 10:44:04 -08003332 *session = (audio_session_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
3333 *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_INPUT);
Eric Laurentc73ca6e2014-12-12 14:34:22 -08003334 *device = getDeviceAndMixForInputSource(AUDIO_SOURCE_HOTWORD);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07003335
François Gaffiedf372692015-03-19 10:43:27 +01003336 return mSoundTriggerSessions.acquireSession(*session, *ioHandle);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07003337}
3338
Eric Laurentd60560a2015-04-10 11:31:20 -07003339status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *source,
3340 const audio_attributes_t *attributes,
Glenn Kasten559d4392016-03-29 13:42:57 -07003341 audio_patch_handle_t *handle,
Eric Laurentd60560a2015-04-10 11:31:20 -07003342 uid_t uid)
Eric Laurent554a2772015-04-10 11:29:24 -07003343{
Eric Laurentd60560a2015-04-10 11:31:20 -07003344 ALOGV("%s source %p attributes %p handle %p", __FUNCTION__, source, attributes, handle);
3345 if (source == NULL || attributes == NULL || handle == NULL) {
3346 return BAD_VALUE;
3347 }
3348
Glenn Kasten559d4392016-03-29 13:42:57 -07003349 *handle = AUDIO_PATCH_HANDLE_NONE;
Eric Laurentd60560a2015-04-10 11:31:20 -07003350
3351 if (source->role != AUDIO_PORT_ROLE_SOURCE ||
3352 source->type != AUDIO_PORT_TYPE_DEVICE) {
3353 ALOGV("%s INVALID_OPERATION source->role %d source->type %d", __FUNCTION__, source->role, source->type);
3354 return INVALID_OPERATION;
3355 }
3356
3357 sp<DeviceDescriptor> srcDeviceDesc =
3358 mAvailableInputDevices.getDevice(source->ext.device.type,
3359 String8(source->ext.device.address));
3360 if (srcDeviceDesc == 0) {
3361 ALOGV("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
3362 return BAD_VALUE;
3363 }
3364 sp<AudioSourceDescriptor> sourceDesc =
3365 new AudioSourceDescriptor(srcDeviceDesc, attributes, uid);
3366
3367 struct audio_patch dummyPatch;
3368 sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
3369 sourceDesc->mPatchDesc = patchDesc;
3370
3371 status_t status = connectAudioSource(sourceDesc);
3372 if (status == NO_ERROR) {
3373 mAudioSources.add(sourceDesc->getHandle(), sourceDesc);
3374 *handle = sourceDesc->getHandle();
3375 }
3376 return status;
3377}
3378
3379status_t AudioPolicyManager::connectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3380{
3381 ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3382
3383 // make sure we only have one patch per source.
3384 disconnectAudioSource(sourceDesc);
3385
3386 routing_strategy strategy = (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
Eric Laurent28d09f02016-03-08 10:43:05 -08003387 audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
Eric Laurentd60560a2015-04-10 11:31:20 -07003388 sp<DeviceDescriptor> srcDeviceDesc = sourceDesc->mDevice;
3389
3390 audio_devices_t sinkDevice = getDeviceForStrategy(strategy, true);
3391 sp<DeviceDescriptor> sinkDeviceDesc =
3392 mAvailableOutputDevices.getDevice(sinkDevice, String8(""));
3393
3394 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
3395 struct audio_patch *patch = &sourceDesc->mPatchDesc->mPatch;
3396
3397 if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
3398 sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
Mikhail Naganov9ee05402016-10-13 15:58:17 -07003399 srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
Eric Laurentd60560a2015-04-10 11:31:20 -07003400 srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
3401 ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
3402 // create patch between src device and output device
3403 // create Hwoutput and add to mHwOutputs
3404 } else {
3405 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
3406 audio_io_handle_t output =
3407 selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
3408 if (output == AUDIO_IO_HANDLE_NONE) {
3409 ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
3410 return INVALID_OPERATION;
3411 }
3412 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
3413 if (outputDesc->isDuplicated()) {
3414 ALOGV("%s output for device %08x is duplicated", __FUNCTION__, sinkDevice);
3415 return INVALID_OPERATION;
3416 }
3417 // create a special patch with no sink and two sources:
3418 // - the second source indicates to PatchPanel through which output mix this patch should
3419 // be connected as well as the stream type for volume control
3420 // - the sink is defined by whatever output device is currently selected for the output
3421 // though which this patch is routed.
3422 patch->num_sinks = 0;
3423 patch->num_sources = 2;
3424 srcDeviceDesc->toAudioPortConfig(&patch->sources[0], NULL);
3425 outputDesc->toAudioPortConfig(&patch->sources[1], NULL);
3426 patch->sources[1].ext.mix.usecase.stream = stream;
3427 status_t status = mpClientInterface->createAudioPatch(patch,
3428 &afPatchHandle,
3429 0);
3430 ALOGV("%s patch panel returned %d patchHandle %d", __FUNCTION__,
3431 status, afPatchHandle);
3432 if (status != NO_ERROR) {
3433 ALOGW("%s patch panel could not connect device patch, error %d",
3434 __FUNCTION__, status);
3435 return INVALID_OPERATION;
3436 }
3437 uint32_t delayMs = 0;
Eric Laurentc40d9692016-04-13 19:14:13 -07003438 status = startSource(outputDesc, stream, sinkDevice, NULL, &delayMs);
Eric Laurentd60560a2015-04-10 11:31:20 -07003439
3440 if (status != NO_ERROR) {
3441 mpClientInterface->releaseAudioPatch(sourceDesc->mPatchDesc->mAfPatchHandle, 0);
3442 return status;
3443 }
3444 sourceDesc->mSwOutput = outputDesc;
3445 if (delayMs != 0) {
3446 usleep(delayMs * 1000);
3447 }
3448 }
3449
3450 sourceDesc->mPatchDesc->mAfPatchHandle = afPatchHandle;
3451 addAudioPatch(sourceDesc->mPatchDesc->mHandle, sourceDesc->mPatchDesc);
3452
3453 return NO_ERROR;
Eric Laurent554a2772015-04-10 11:29:24 -07003454}
3455
Glenn Kasten559d4392016-03-29 13:42:57 -07003456status_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle __unused)
Eric Laurent554a2772015-04-10 11:29:24 -07003457{
Eric Laurentd60560a2015-04-10 11:31:20 -07003458 sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
3459 ALOGV("%s handle %d", __FUNCTION__, handle);
3460 if (sourceDesc == 0) {
3461 ALOGW("%s unknown source for handle %d", __FUNCTION__, handle);
3462 return BAD_VALUE;
3463 }
3464 status_t status = disconnectAudioSource(sourceDesc);
3465
3466 mAudioSources.removeItem(handle);
3467 return status;
3468}
3469
Andy Hung2ddee192015-12-18 17:34:44 -08003470status_t AudioPolicyManager::setMasterMono(bool mono)
3471{
3472 if (mMasterMono == mono) {
3473 return NO_ERROR;
3474 }
3475 mMasterMono = mono;
3476 // if enabling mono we close all offloaded devices, which will invalidate the
3477 // corresponding AudioTrack. The AudioTrack client/MediaPlayer is responsible
3478 // for recreating the new AudioTrack as non-offloaded PCM.
3479 //
3480 // If disabling mono, we leave all tracks as is: we don't know which clients
3481 // and tracks are able to be recreated as offloaded. The next "song" should
3482 // play back offloaded.
3483 if (mMasterMono) {
3484 Vector<audio_io_handle_t> offloaded;
3485 for (size_t i = 0; i < mOutputs.size(); ++i) {
3486 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
3487 if (desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
3488 offloaded.push(desc->mIoHandle);
3489 }
3490 }
3491 for (size_t i = 0; i < offloaded.size(); ++i) {
3492 closeOutput(offloaded[i]);
3493 }
3494 }
3495 // update master mono for all remaining outputs
3496 for (size_t i = 0; i < mOutputs.size(); ++i) {
3497 updateMono(mOutputs.keyAt(i));
3498 }
3499 return NO_ERROR;
3500}
3501
3502status_t AudioPolicyManager::getMasterMono(bool *mono)
3503{
3504 *mono = mMasterMono;
3505 return NO_ERROR;
3506}
3507
Eric Laurentac9cef52017-06-09 15:46:26 -07003508float AudioPolicyManager::getStreamVolumeDB(
3509 audio_stream_type_t stream, int index, audio_devices_t device)
3510{
3511 return computeVolume(stream, index, device);
3512}
3513
Eric Laurentd60560a2015-04-10 11:31:20 -07003514status_t AudioPolicyManager::disconnectAudioSource(const sp<AudioSourceDescriptor>& sourceDesc)
3515{
3516 ALOGV("%s handle %d", __FUNCTION__, sourceDesc->getHandle());
3517
3518 sp<AudioPatch> patchDesc = mAudioPatches.valueFor(sourceDesc->mPatchDesc->mHandle);
3519 if (patchDesc == 0) {
3520 ALOGW("%s source has no patch with handle %d", __FUNCTION__,
3521 sourceDesc->mPatchDesc->mHandle);
3522 return BAD_VALUE;
3523 }
3524 removeAudioPatch(sourceDesc->mPatchDesc->mHandle);
3525
Eric Laurent28d09f02016-03-08 10:43:05 -08003526 audio_stream_type_t stream = streamTypefromAttributesInt(&sourceDesc->mAttributes);
Eric Laurentd60560a2015-04-10 11:31:20 -07003527 sp<SwAudioOutputDescriptor> swOutputDesc = sourceDesc->mSwOutput.promote();
3528 if (swOutputDesc != 0) {
3529 stopSource(swOutputDesc, stream, false);
3530 mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
3531 } else {
3532 sp<HwAudioOutputDescriptor> hwOutputDesc = sourceDesc->mHwOutput.promote();
3533 if (hwOutputDesc != 0) {
3534 // release patch between src device and output device
3535 // close Hwoutput and remove from mHwOutputs
3536 } else {
3537 ALOGW("%s source has neither SW nor HW output", __FUNCTION__);
3538 }
3539 }
3540 return NO_ERROR;
3541}
3542
3543sp<AudioSourceDescriptor> AudioPolicyManager::getSourceForStrategyOnOutput(
3544 audio_io_handle_t output, routing_strategy strategy)
3545{
3546 sp<AudioSourceDescriptor> source;
3547 for (size_t i = 0; i < mAudioSources.size(); i++) {
3548 sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
3549 routing_strategy sourceStrategy =
3550 (routing_strategy) getStrategyForAttr(&sourceDesc->mAttributes);
3551 sp<SwAudioOutputDescriptor> outputDesc = sourceDesc->mSwOutput.promote();
3552 if (sourceStrategy == strategy && outputDesc != 0 && outputDesc->mIoHandle == output) {
3553 source = sourceDesc;
3554 break;
3555 }
3556 }
3557 return source;
Eric Laurent554a2772015-04-10 11:29:24 -07003558}
3559
Eric Laurente552edb2014-03-10 17:42:56 -07003560// ----------------------------------------------------------------------------
Eric Laurente0720872014-03-11 09:30:41 -07003561// AudioPolicyManager
Eric Laurente552edb2014-03-10 17:42:56 -07003562// ----------------------------------------------------------------------------
Eric Laurent6a94d692014-05-20 11:18:06 -07003563uint32_t AudioPolicyManager::nextAudioPortGeneration()
3564{
3565 return android_atomic_inc(&mAudioPortGeneration);
3566}
3567
Jaekyun Seok0d4a6af2017-02-17 17:10:17 +09003568#ifdef USE_XML_AUDIO_POLICY_CONF
3569// Treblized audio policy xml config will be located in /odm/etc or /vendor/etc.
3570static const char *kConfigLocationList[] =
3571 {"/odm/etc", "/vendor/etc", "/system/etc"};
3572static const int kConfigLocationListSize =
3573 (sizeof(kConfigLocationList) / sizeof(kConfigLocationList[0]));
3574
3575static status_t deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) {
3576 char audioPolicyXmlConfigFile[AUDIO_POLICY_XML_CONFIG_FILE_PATH_MAX_LENGTH];
Petri Gyntherf497f292018-04-17 18:46:10 -07003577 std::vector<const char*> fileNames;
Jaekyun Seok0d4a6af2017-02-17 17:10:17 +09003578 status_t ret;
3579
Petri Gyntherf497f292018-04-17 18:46:10 -07003580 if (property_get_bool("ro.bluetooth.a2dp_offload.supported", false) &&
3581 property_get_bool("persist.bluetooth.a2dp_offload.disabled", false)) {
3582 // A2DP offload supported but disabled: try to use special XML file
3583 fileNames.push_back(AUDIO_POLICY_A2DP_OFFLOAD_DISABLED_XML_CONFIG_FILE_NAME);
3584 }
3585 fileNames.push_back(AUDIO_POLICY_XML_CONFIG_FILE_NAME);
3586
3587 for (const char* fileName : fileNames) {
3588 for (int i = 0; i < kConfigLocationListSize; i++) {
3589 PolicySerializer serializer;
3590 snprintf(audioPolicyXmlConfigFile, sizeof(audioPolicyXmlConfigFile),
3591 "%s/%s", kConfigLocationList[i], fileName);
3592 ret = serializer.deserialize(audioPolicyXmlConfigFile, config);
3593 if (ret == NO_ERROR) {
3594 return ret;
3595 }
Jaekyun Seok0d4a6af2017-02-17 17:10:17 +09003596 }
3597 }
3598 return ret;
3599}
3600#endif
3601
Eric Laurente0720872014-03-11 09:30:41 -07003602AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
Eric Laurente552edb2014-03-10 17:42:56 -07003603 :
3604#ifdef AUDIO_POLICY_TEST
3605 Thread(false),
3606#endif //AUDIO_POLICY_TEST
Eric Laurente552edb2014-03-10 17:42:56 -07003607 mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
Eric Laurent3a4311c2014-03-17 12:00:47 -07003608 mA2dpSuspended(false),
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07003609 mAudioPortGeneration(1),
3610 mBeaconMuteRefCount(0),
3611 mBeaconPlayingRefCount(0),
Eric Laurent9459fb02015-08-12 18:36:32 -07003612 mBeaconMuted(false),
Andy Hung2ddee192015-12-18 17:34:44 -08003613 mTtsOutputAvailable(false),
Eric Laurent36829f92017-04-07 19:04:42 -07003614 mMasterMono(false),
Chris Thornton2b864642017-06-27 21:26:07 -07003615 mMusicEffectOutput(AUDIO_IO_HANDLE_NONE),
3616 mHasComputedSoundTriggerSupportsConcurrentCapture(false)
Eric Laurente552edb2014-03-10 17:42:56 -07003617{
François Gaffied1ab2bd2015-12-02 18:20:06 +01003618 mUidCached = getuid();
3619 mpClientInterface = clientInterface;
3620
3621 // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
3622 // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
3623 // Note: remove also speaker_drc_enabled from global configuration of XML config file.
3624 bool speakerDrcEnabled = false;
3625
3626#ifdef USE_XML_AUDIO_POLICY_CONF
3627 mVolumeCurves = new VolumeCurvesCollection();
3628 AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3629 mDefaultOutputDevice, speakerDrcEnabled,
3630 static_cast<VolumeCurvesCollection *>(mVolumeCurves));
Jaekyun Seok0d4a6af2017-02-17 17:10:17 +09003631 if (deserializeAudioPolicyXmlConfig(config) != NO_ERROR) {
François Gaffied1ab2bd2015-12-02 18:20:06 +01003632#else
3633 mVolumeCurves = new StreamDescriptorCollection();
3634 AudioPolicyConfig config(mHwModules, mAvailableOutputDevices, mAvailableInputDevices,
3635 mDefaultOutputDevice, speakerDrcEnabled);
3636 if ((ConfigParsingUtils::loadConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, config) != NO_ERROR) &&
3637 (ConfigParsingUtils::loadConfig(AUDIO_POLICY_CONFIG_FILE, config) != NO_ERROR)) {
3638#endif
3639 ALOGE("could not load audio policy configuration file, setting defaults");
3640 config.setDefault();
3641 }
3642 // must be done after reading the policy (since conditionned by Speaker Drc Enabling)
3643 mVolumeCurves->initializeVolumeCurves(speakerDrcEnabled);
3644
3645 // Once policy config has been parsed, retrieve an instance of the engine and initialize it.
François Gaffie2110e042015-03-24 08:41:51 +01003646 audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
3647 if (!engineInstance) {
3648 ALOGE("%s: Could not get an instance of policy engine", __FUNCTION__);
3649 return;
3650 }
3651 // Retrieve the Policy Manager Interface
3652 mEngine = engineInstance->queryInterface<AudioPolicyManagerInterface>();
3653 if (mEngine == NULL) {
3654 ALOGE("%s: Failed to get Policy Engine Interface", __FUNCTION__);
3655 return;
3656 }
3657 mEngine->setObserver(this);
3658 status_t status = mEngine->initCheck();
Glenn Kastenfcddb0b2016-07-08 17:19:25 -07003659 (void) status;
François Gaffie2110e042015-03-24 08:41:51 +01003660 ALOG_ASSERT(status == NO_ERROR, "Policy engine not initialized(err=%d)", status);
3661
Eric Laurent3a4311c2014-03-17 12:00:47 -07003662 // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
Eric Laurente552edb2014-03-10 17:42:56 -07003663 // open all output streams needed to access attached devices
Eric Laurent3a4311c2014-03-17 12:00:47 -07003664 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
3665 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
Eric Laurente552edb2014-03-10 17:42:56 -07003666 for (size_t i = 0; i < mHwModules.size(); i++) {
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003667 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->getName());
Eric Laurente552edb2014-03-10 17:42:56 -07003668 if (mHwModules[i]->mHandle == 0) {
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003669 ALOGW("could not open HW module %s", mHwModules[i]->getName());
Eric Laurente552edb2014-03-10 17:42:56 -07003670 continue;
3671 }
3672 // open all output streams needed to access attached devices
3673 // except for direct output streams that are only opened when they are actually
3674 // required by an app.
Eric Laurent3a4311c2014-03-17 12:00:47 -07003675 // This also validates mAvailableOutputDevices list
Eric Laurente552edb2014-03-10 17:42:56 -07003676 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3677 {
Eric Laurent1c333e22014-05-20 10:48:17 -07003678 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07003679
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003680 if (!outProfile->hasSupportedDevices()) {
3681 ALOGW("Output profile contains no device on module %s", mHwModules[i]->getName());
Eric Laurent3a4311c2014-03-17 12:00:47 -07003682 continue;
3683 }
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003684 if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_TTS) != 0) {
Eric Laurent9459fb02015-08-12 18:36:32 -07003685 mTtsOutputAvailable = true;
3686 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003687
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003688 if ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
Eric Laurentd78f1532014-09-16 16:38:20 -07003689 continue;
3690 }
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003691 audio_devices_t profileType = outProfile->getSupportedDevicesType();
François Gaffie53615e22015-03-19 09:24:12 +01003692 if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) {
3693 profileType = mDefaultOutputDevice->type();
Eric Laurent83b88082014-06-20 18:31:16 -07003694 } else {
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003695 // chose first device present in profile's SupportedDevices also part of
Eric Laurentd78f1532014-09-16 16:38:20 -07003696 // outputDeviceTypes
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003697 profileType = outProfile->getSupportedDeviceForType(outputDeviceTypes);
Eric Laurente552edb2014-03-10 17:42:56 -07003698 }
Eric Laurentd78f1532014-09-16 16:38:20 -07003699 if ((profileType & outputDeviceTypes) == 0) {
3700 continue;
3701 }
Eric Laurentc75307b2015-03-17 15:29:32 -07003702 sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
3703 mpClientInterface);
Eric Laurentc40d9692016-04-13 19:14:13 -07003704 const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
3705 const DeviceVector &devicesForType = supportedDevices.getDevicesFromType(profileType);
3706 String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
3707 : String8("");
Eric Laurentd78f1532014-09-16 16:38:20 -07003708
3709 outputDesc->mDevice = profileType;
3710 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3711 config.sample_rate = outputDesc->mSamplingRate;
3712 config.channel_mask = outputDesc->mChannelMask;
3713 config.format = outputDesc->mFormat;
3714 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07003715 status_t status = mpClientInterface->openOutput(outProfile->getModuleHandle(),
Eric Laurentd78f1532014-09-16 16:38:20 -07003716 &output,
3717 &config,
3718 &outputDesc->mDevice,
Eric Laurentc40d9692016-04-13 19:14:13 -07003719 address,
Eric Laurentd78f1532014-09-16 16:38:20 -07003720 &outputDesc->mLatency,
3721 outputDesc->mFlags);
3722
3723 if (status != NO_ERROR) {
3724 ALOGW("Cannot open output stream for device %08x on hw module %s",
3725 outputDesc->mDevice,
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003726 mHwModules[i]->getName());
Eric Laurentd78f1532014-09-16 16:38:20 -07003727 } else {
3728 outputDesc->mSamplingRate = config.sample_rate;
3729 outputDesc->mChannelMask = config.channel_mask;
3730 outputDesc->mFormat = config.format;
3731
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003732 for (size_t k = 0; k < supportedDevices.size(); k++) {
3733 ssize_t index = mAvailableOutputDevices.indexOf(supportedDevices[k]);
Eric Laurentd78f1532014-09-16 16:38:20 -07003734 // give a valid ID to an attached device once confirmed it is reachable
Paul McLeane743a472015-01-28 11:07:31 -08003735 if (index >= 0 && !mAvailableOutputDevices[index]->isAttached()) {
3736 mAvailableOutputDevices[index]->attach(mHwModules[i]);
Eric Laurentd78f1532014-09-16 16:38:20 -07003737 }
3738 }
3739 if (mPrimaryOutput == 0 &&
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003740 outProfile->getFlags() & AUDIO_OUTPUT_FLAG_PRIMARY) {
Eric Laurentc75307b2015-03-17 15:29:32 -07003741 mPrimaryOutput = outputDesc;
Eric Laurentd78f1532014-09-16 16:38:20 -07003742 }
3743 addOutput(output, outputDesc);
Eric Laurentc75307b2015-03-17 15:29:32 -07003744 setOutputDevice(outputDesc,
Eric Laurentd78f1532014-09-16 16:38:20 -07003745 outputDesc->mDevice,
Eric Laurentc40d9692016-04-13 19:14:13 -07003746 true,
3747 0,
3748 NULL,
3749 address.string());
Eric Laurentd78f1532014-09-16 16:38:20 -07003750 }
Eric Laurente552edb2014-03-10 17:42:56 -07003751 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003752 // open input streams needed to access attached devices to validate
3753 // mAvailableInputDevices list
3754 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
3755 {
Eric Laurent1c333e22014-05-20 10:48:17 -07003756 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07003757
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003758 if (!inProfile->hasSupportedDevices()) {
3759 ALOGW("Input profile contains no device on module %s", mHwModules[i]->getName());
Eric Laurent3a4311c2014-03-17 12:00:47 -07003760 continue;
3761 }
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003762 // chose first device present in profile's SupportedDevices also part of
Eric Laurentd78f1532014-09-16 16:38:20 -07003763 // inputDeviceTypes
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003764 audio_devices_t profileType = inProfile->getSupportedDeviceForType(inputDeviceTypes);
3765
Eric Laurentd78f1532014-09-16 16:38:20 -07003766 if ((profileType & inputDeviceTypes) == 0) {
3767 continue;
3768 }
Jean-Michel Trivi2f4fe9f2015-12-04 16:20:59 -08003769 sp<AudioInputDescriptor> inputDesc =
3770 new AudioInputDescriptor(inProfile);
Eric Laurentd78f1532014-09-16 16:38:20 -07003771
Eric Laurentd78f1532014-09-16 16:38:20 -07003772 inputDesc->mDevice = profileType;
3773
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07003774 // find the address
3775 DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromType(profileType);
3776 // the inputs vector must be of size 1, but we don't want to crash here
3777 String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
3778 : String8("");
3779 ALOGV(" for input device 0x%x using address %s", profileType, address.string());
3780 ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
3781
Eric Laurentd78f1532014-09-16 16:38:20 -07003782 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3783 config.sample_rate = inputDesc->mSamplingRate;
3784 config.channel_mask = inputDesc->mChannelMask;
3785 config.format = inputDesc->mFormat;
3786 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07003787 status_t status = mpClientInterface->openInput(inProfile->getModuleHandle(),
Eric Laurentd78f1532014-09-16 16:38:20 -07003788 &input,
3789 &config,
3790 &inputDesc->mDevice,
Jean-Michel Trivifd4c1482014-08-06 16:02:28 -07003791 address,
Eric Laurentd78f1532014-09-16 16:38:20 -07003792 AUDIO_SOURCE_MIC,
3793 AUDIO_INPUT_FLAG_NONE);
3794
3795 if (status == NO_ERROR) {
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003796 const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
3797 for (size_t k = 0; k < supportedDevices.size(); k++) {
3798 ssize_t index = mAvailableInputDevices.indexOf(supportedDevices[k]);
Eric Laurentd78f1532014-09-16 16:38:20 -07003799 // give a valid ID to an attached device once confirmed it is reachable
Eric Laurent45aabc32015-08-06 09:11:13 -07003800 if (index >= 0) {
3801 sp<DeviceDescriptor> devDesc = mAvailableInputDevices[index];
3802 if (!devDesc->isAttached()) {
3803 devDesc->attach(mHwModules[i]);
Eric Laurent83efe1c2017-07-09 16:51:08 -07003804 devDesc->importAudioPort(inProfile, true);
Eric Laurent45aabc32015-08-06 09:11:13 -07003805 }
Eric Laurentd78f1532014-09-16 16:38:20 -07003806 }
3807 }
3808 mpClientInterface->closeInput(input);
3809 } else {
3810 ALOGW("Cannot open input stream for device %08x on hw module %s",
3811 inputDesc->mDevice,
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003812 mHwModules[i]->getName());
Eric Laurentd78f1532014-09-16 16:38:20 -07003813 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003814 }
3815 }
3816 // make sure all attached devices have been allocated a unique ID
3817 for (size_t i = 0; i < mAvailableOutputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08003818 if (!mAvailableOutputDevices[i]->isAttached()) {
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003819 ALOGW("Output device %08x unreachable", mAvailableOutputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07003820 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
3821 continue;
3822 }
François Gaffie2110e042015-03-24 08:41:51 +01003823 // The device is now validated and can be appended to the available devices of the engine
3824 mEngine->setDeviceConnectionState(mAvailableOutputDevices[i],
3825 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07003826 i++;
3827 }
3828 for (size_t i = 0; i < mAvailableInputDevices.size();) {
Paul McLeane743a472015-01-28 11:07:31 -08003829 if (!mAvailableInputDevices[i]->isAttached()) {
François Gaffie53615e22015-03-19 09:24:12 +01003830 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07003831 mAvailableInputDevices.remove(mAvailableInputDevices[i]);
3832 continue;
3833 }
François Gaffie2110e042015-03-24 08:41:51 +01003834 // The device is now validated and can be appended to the available devices of the engine
3835 mEngine->setDeviceConnectionState(mAvailableInputDevices[i],
3836 AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
Eric Laurent3a4311c2014-03-17 12:00:47 -07003837 i++;
3838 }
3839 // make sure default device is reachable
François Gaffiea8ecc2c2015-11-09 16:10:40 +01003840 if (mDefaultOutputDevice == 0 || mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
François Gaffie53615e22015-03-19 09:24:12 +01003841 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
Eric Laurent3a4311c2014-03-17 12:00:47 -07003842 }
Eric Laurente552edb2014-03-10 17:42:56 -07003843
3844 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
3845
3846 updateDevicesAndOutputs();
3847
3848#ifdef AUDIO_POLICY_TEST
3849 if (mPrimaryOutput != 0) {
3850 AudioParameter outputCmd = AudioParameter();
3851 outputCmd.addInt(String8("set_id"), 0);
Eric Laurentc75307b2015-03-17 15:29:32 -07003852 mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, outputCmd.toString());
Eric Laurente552edb2014-03-10 17:42:56 -07003853
3854 mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
3855 mTestSamplingRate = 44100;
Eric Laurent3b73df72014-03-11 09:06:29 -07003856 mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
3857 mTestChannels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07003858 mTestLatencyMs = 0;
3859 mCurOutput = 0;
3860 mDirectOutput = false;
3861 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
3862 mTestOutputs[i] = 0;
3863 }
3864
3865 const size_t SIZE = 256;
3866 char buffer[SIZE];
3867 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
3868 run(buffer, ANDROID_PRIORITY_AUDIO);
3869 }
3870#endif //AUDIO_POLICY_TEST
3871}
3872
Eric Laurente0720872014-03-11 09:30:41 -07003873AudioPolicyManager::~AudioPolicyManager()
Eric Laurente552edb2014-03-10 17:42:56 -07003874{
3875#ifdef AUDIO_POLICY_TEST
3876 exit();
3877#endif //AUDIO_POLICY_TEST
3878 for (size_t i = 0; i < mOutputs.size(); i++) {
3879 mpClientInterface->closeOutput(mOutputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07003880 }
3881 for (size_t i = 0; i < mInputs.size(); i++) {
3882 mpClientInterface->closeInput(mInputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07003883 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003884 mAvailableOutputDevices.clear();
3885 mAvailableInputDevices.clear();
Eric Laurent1f2f2232014-06-02 12:01:23 -07003886 mOutputs.clear();
3887 mInputs.clear();
3888 mHwModules.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07003889}
3890
Eric Laurente0720872014-03-11 09:30:41 -07003891status_t AudioPolicyManager::initCheck()
Eric Laurente552edb2014-03-10 17:42:56 -07003892{
Eric Laurent87ffa392015-05-22 10:32:38 -07003893 return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003894}
3895
3896#ifdef AUDIO_POLICY_TEST
Eric Laurente0720872014-03-11 09:30:41 -07003897bool AudioPolicyManager::threadLoop()
Eric Laurente552edb2014-03-10 17:42:56 -07003898{
3899 ALOGV("entering threadLoop()");
3900 while (!exitPending())
3901 {
3902 String8 command;
3903 int valueInt;
3904 String8 value;
3905
3906 Mutex::Autolock _l(mLock);
3907 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
3908
3909 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
3910 AudioParameter param = AudioParameter(command);
3911
3912 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
3913 valueInt != 0) {
3914 ALOGV("Test command %s received", command.string());
3915 String8 target;
3916 if (param.get(String8("target"), target) != NO_ERROR) {
3917 target = "Manager";
3918 }
3919 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
3920 param.remove(String8("test_cmd_policy_output"));
3921 mCurOutput = valueInt;
3922 }
3923 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
3924 param.remove(String8("test_cmd_policy_direct"));
3925 if (value == "false") {
3926 mDirectOutput = false;
3927 } else if (value == "true") {
3928 mDirectOutput = true;
3929 }
3930 }
3931 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
3932 param.remove(String8("test_cmd_policy_input"));
3933 mTestInput = valueInt;
3934 }
3935
3936 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
3937 param.remove(String8("test_cmd_policy_format"));
Eric Laurent3b73df72014-03-11 09:06:29 -07003938 int format = AUDIO_FORMAT_INVALID;
Eric Laurente552edb2014-03-10 17:42:56 -07003939 if (value == "PCM 16 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003940 format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003941 } else if (value == "PCM 8 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003942 format = AUDIO_FORMAT_PCM_8_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003943 } else if (value == "Compressed MP3") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003944 format = AUDIO_FORMAT_MP3;
Eric Laurente552edb2014-03-10 17:42:56 -07003945 }
Eric Laurent3b73df72014-03-11 09:06:29 -07003946 if (format != AUDIO_FORMAT_INVALID) {
Eric Laurente552edb2014-03-10 17:42:56 -07003947 if (target == "Manager") {
3948 mTestFormat = format;
3949 } else if (mTestOutputs[mCurOutput] != 0) {
3950 AudioParameter outputParam = AudioParameter();
Mikhail Naganov388360c2016-10-17 17:09:41 -07003951 outputParam.addInt(String8(AudioParameter::keyStreamSupportedFormats), format);
Eric Laurente552edb2014-03-10 17:42:56 -07003952 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3953 }
3954 }
3955 }
3956 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
3957 param.remove(String8("test_cmd_policy_channels"));
3958 int channels = 0;
3959
3960 if (value == "Channels Stereo") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003961 channels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07003962 } else if (value == "Channels Mono") {
Eric Laurent3b73df72014-03-11 09:06:29 -07003963 channels = AUDIO_CHANNEL_OUT_MONO;
Eric Laurente552edb2014-03-10 17:42:56 -07003964 }
3965 if (channels != 0) {
3966 if (target == "Manager") {
3967 mTestChannels = channels;
3968 } else if (mTestOutputs[mCurOutput] != 0) {
3969 AudioParameter outputParam = AudioParameter();
Mikhail Naganov388360c2016-10-17 17:09:41 -07003970 outputParam.addInt(String8(AudioParameter::keyStreamSupportedChannels), channels);
Eric Laurente552edb2014-03-10 17:42:56 -07003971 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3972 }
3973 }
3974 }
3975 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
3976 param.remove(String8("test_cmd_policy_sampleRate"));
3977 if (valueInt >= 0 && valueInt <= 96000) {
3978 int samplingRate = valueInt;
3979 if (target == "Manager") {
3980 mTestSamplingRate = samplingRate;
3981 } else if (mTestOutputs[mCurOutput] != 0) {
3982 AudioParameter outputParam = AudioParameter();
Mikhail Naganov388360c2016-10-17 17:09:41 -07003983 outputParam.addInt(String8(AudioParameter::keyStreamSupportedSamplingRates), samplingRate);
Eric Laurente552edb2014-03-10 17:42:56 -07003984 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
3985 }
3986 }
3987 }
3988
3989 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
3990 param.remove(String8("test_cmd_policy_reopen"));
3991
Eric Laurentc75307b2015-03-17 15:29:32 -07003992 mpClientInterface->closeOutput(mpClientInterface->closeOutput(mPrimaryOutput););
Eric Laurente552edb2014-03-10 17:42:56 -07003993
Eric Laurentc75307b2015-03-17 15:29:32 -07003994 audio_module_handle_t moduleHandle = mPrimaryOutput->getModuleHandle();
Eric Laurente552edb2014-03-10 17:42:56 -07003995
Eric Laurentc75307b2015-03-17 15:29:32 -07003996 removeOutput(mPrimaryOutput->mIoHandle);
3997 sp<SwAudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL,
3998 mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -07003999 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurentcf2c0212014-07-25 16:20:43 -07004000 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4001 config.sample_rate = outputDesc->mSamplingRate;
4002 config.channel_mask = outputDesc->mChannelMask;
4003 config.format = outputDesc->mFormat;
Eric Laurentc75307b2015-03-17 15:29:32 -07004004 audio_io_handle_t handle;
Eric Laurentcf2c0212014-07-25 16:20:43 -07004005 status_t status = mpClientInterface->openOutput(moduleHandle,
Eric Laurentc75307b2015-03-17 15:29:32 -07004006 &handle,
Eric Laurentcf2c0212014-07-25 16:20:43 -07004007 &config,
4008 &outputDesc->mDevice,
4009 String8(""),
4010 &outputDesc->mLatency,
4011 outputDesc->mFlags);
4012 if (status != NO_ERROR) {
4013 ALOGE("Failed to reopen hardware output stream, "
4014 "samplingRate: %d, format %d, channels %d",
4015 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
Eric Laurente552edb2014-03-10 17:42:56 -07004016 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07004017 outputDesc->mSamplingRate = config.sample_rate;
4018 outputDesc->mChannelMask = config.channel_mask;
4019 outputDesc->mFormat = config.format;
Eric Laurentc75307b2015-03-17 15:29:32 -07004020 mPrimaryOutput = outputDesc;
Eric Laurente552edb2014-03-10 17:42:56 -07004021 AudioParameter outputCmd = AudioParameter();
4022 outputCmd.addInt(String8("set_id"), 0);
Eric Laurentc75307b2015-03-17 15:29:32 -07004023 mpClientInterface->setParameters(handle, outputCmd.toString());
4024 addOutput(handle, outputDesc);
Eric Laurente552edb2014-03-10 17:42:56 -07004025 }
4026 }
4027
4028
4029 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
4030 }
4031 }
4032 return false;
4033}
4034
Eric Laurente0720872014-03-11 09:30:41 -07004035void AudioPolicyManager::exit()
Eric Laurente552edb2014-03-10 17:42:56 -07004036{
4037 {
4038 AutoMutex _l(mLock);
4039 requestExit();
4040 mWaitWorkCV.signal();
4041 }
4042 requestExitAndWait();
4043}
4044
Eric Laurente0720872014-03-11 09:30:41 -07004045int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07004046{
4047 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
4048 if (output == mTestOutputs[i]) return i;
4049 }
4050 return 0;
4051}
4052#endif //AUDIO_POLICY_TEST
4053
4054// ---
4055
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004056void AudioPolicyManager::addOutput(audio_io_handle_t output, const sp<SwAudioOutputDescriptor>& outputDesc)
Eric Laurente552edb2014-03-10 17:42:56 -07004057{
François Gaffie98cc1912015-03-18 17:52:40 +01004058 outputDesc->setIoHandle(output);
Eric Laurent1c333e22014-05-20 10:48:17 -07004059 mOutputs.add(output, outputDesc);
Andy Hung2ddee192015-12-18 17:34:44 -08004060 updateMono(output); // update mono status when adding to output list
Eric Laurent36829f92017-04-07 19:04:42 -07004061 selectOutputForMusicEffects();
Eric Laurent6a94d692014-05-20 11:18:06 -07004062 nextAudioPortGeneration();
Eric Laurente552edb2014-03-10 17:42:56 -07004063}
4064
François Gaffie53615e22015-03-19 09:24:12 +01004065void AudioPolicyManager::removeOutput(audio_io_handle_t output)
4066{
4067 mOutputs.removeItem(output);
Eric Laurent36829f92017-04-07 19:04:42 -07004068 selectOutputForMusicEffects();
François Gaffie53615e22015-03-19 09:24:12 +01004069}
4070
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004071void AudioPolicyManager::addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc)
Eric Laurentd4692962014-05-05 18:13:44 -07004072{
François Gaffie98cc1912015-03-18 17:52:40 +01004073 inputDesc->setIoHandle(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07004074 mInputs.add(input, inputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07004075 nextAudioPortGeneration();
Eric Laurentd4692962014-05-05 18:13:44 -07004076}
Eric Laurente552edb2014-03-10 17:42:56 -07004077
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004078void AudioPolicyManager::findIoHandlesByAddress(const sp<SwAudioOutputDescriptor>& desc /*in*/,
keunyoung3190e672014-12-30 13:00:52 -08004079 const audio_devices_t device /*in*/,
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004080 const String8& address /*in*/,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004081 SortedVector<audio_io_handle_t>& outputs /*out*/) {
keunyoung3190e672014-12-30 13:00:52 -08004082 sp<DeviceDescriptor> devDesc =
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004083 desc->mProfile->getSupportedDeviceByAddress(device, address);
keunyoung3190e672014-12-30 13:00:52 -08004084 if (devDesc != 0) {
4085 ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
4086 desc->mIoHandle, address.string());
4087 outputs.add(desc->mIoHandle);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004088 }
4089}
4090
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004091status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& devDesc,
François Gaffie53615e22015-03-19 09:24:12 +01004092 audio_policy_dev_state_t state,
4093 SortedVector<audio_io_handle_t>& outputs,
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004094 const String8& address)
Eric Laurente552edb2014-03-10 17:42:56 -07004095{
François Gaffie53615e22015-03-19 09:24:12 +01004096 audio_devices_t device = devDesc->type();
Eric Laurentc75307b2015-03-17 15:29:32 -07004097 sp<SwAudioOutputDescriptor> desc;
Eric Laurentcc750d32015-06-25 11:48:20 -07004098
4099 if (audio_device_is_digital(device)) {
4100 // erase all current sample rates, formats and channel masks
Eric Laurent20eb3a42016-01-26 18:39:17 -08004101 devDesc->clearAudioProfiles();
Eric Laurentcc750d32015-06-25 11:48:20 -07004102 }
Eric Laurente552edb2014-03-10 17:42:56 -07004103
Eric Laurent3b73df72014-03-11 09:06:29 -07004104 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
Eric Laurente552edb2014-03-10 17:42:56 -07004105 // first list already open outputs that can be routed to this device
4106 for (size_t i = 0; i < mOutputs.size(); i++) {
4107 desc = mOutputs.valueAt(i);
Eric Laurentc75307b2015-03-17 15:29:32 -07004108 if (!desc->isDuplicated() && (desc->supportedDevices() & device)) {
François Gaffie53615e22015-03-19 09:24:12 +01004109 if (!device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004110 ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
4111 outputs.add(mOutputs.keyAt(i));
4112 } else {
4113 ALOGV(" checking address match due to device 0x%x", device);
keunyoung3190e672014-12-30 13:00:52 -08004114 findIoHandlesByAddress(desc, device, address, outputs);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004115 }
Eric Laurente552edb2014-03-10 17:42:56 -07004116 }
4117 }
4118 // then look for output profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07004119 SortedVector< sp<IOProfile> > profiles;
Eric Laurente552edb2014-03-10 17:42:56 -07004120 for (size_t i = 0; i < mHwModules.size(); i++)
4121 {
4122 if (mHwModules[i]->mHandle == 0) {
4123 continue;
4124 }
4125 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
4126 {
Eric Laurent275e8e92014-11-30 15:14:47 -08004127 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004128 if (profile->supportDevice(device)) {
François Gaffie53615e22015-03-19 09:24:12 +01004129 if (!device_distinguishes_on_address(device) ||
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004130 profile->supportDeviceAddress(address)) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004131 profiles.add(profile);
4132 ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
4133 }
Eric Laurente552edb2014-03-10 17:42:56 -07004134 }
4135 }
4136 }
4137
Eric Laurent7b279bb2015-12-14 10:18:23 -08004138 ALOGV(" found %zu profiles, %zu outputs", profiles.size(), outputs.size());
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004139
Eric Laurente552edb2014-03-10 17:42:56 -07004140 if (profiles.isEmpty() && outputs.isEmpty()) {
4141 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
4142 return BAD_VALUE;
4143 }
4144
4145 // open outputs for matching profiles if needed. Direct outputs are also opened to
4146 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4147 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004148 sp<IOProfile> profile = profiles[profile_index];
Eric Laurente552edb2014-03-10 17:42:56 -07004149
4150 // nothing to do if one output is already opened for this profile
4151 size_t j;
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004152 for (j = 0; j < outputs.size(); j++) {
4153 desc = mOutputs.valueFor(outputs.itemAt(j));
Eric Laurente552edb2014-03-10 17:42:56 -07004154 if (!desc->isDuplicated() && desc->mProfile == profile) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07004155 // matching profile: save the sample rates, format and channel masks supported
4156 // by the profile in our device descriptor
Paul McLean9080a4c2015-06-18 08:24:02 -07004157 if (audio_device_is_digital(device)) {
4158 devDesc->importAudioPort(profile);
4159 }
Eric Laurente552edb2014-03-10 17:42:56 -07004160 break;
4161 }
4162 }
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004163 if (j != outputs.size()) {
Eric Laurente552edb2014-03-10 17:42:56 -07004164 continue;
4165 }
4166
Eric Laurent83efe1c2017-07-09 16:51:08 -07004167 ALOGV("opening output for device %08x with params %s profile %p name %s",
4168 device, address.string(), profile.get(), profile->getName().string());
Eric Laurentc75307b2015-03-17 15:29:32 -07004169 desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
Eric Laurente552edb2014-03-10 17:42:56 -07004170 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07004171 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4172 config.sample_rate = desc->mSamplingRate;
4173 config.channel_mask = desc->mChannelMask;
4174 config.format = desc->mFormat;
4175 config.offload_info.sample_rate = desc->mSamplingRate;
4176 config.offload_info.channel_mask = desc->mChannelMask;
4177 config.offload_info.format = desc->mFormat;
4178 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Eric Laurent322b4d22015-04-03 15:57:54 -07004179 status_t status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07004180 &output,
4181 &config,
4182 &desc->mDevice,
4183 address,
4184 &desc->mLatency,
4185 desc->mFlags);
4186 if (status == NO_ERROR) {
4187 desc->mSamplingRate = config.sample_rate;
4188 desc->mChannelMask = config.channel_mask;
4189 desc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07004190
Eric Laurentd4692962014-05-05 18:13:44 -07004191 // Here is where the out_set_parameters() for card & device gets called
Eric Laurent3a4311c2014-03-17 12:00:47 -07004192 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07004193 char *param = audio_device_address_to_parameter(device, address);
4194 mpClientInterface->setParameters(output, String8(param));
4195 free(param);
Eric Laurente552edb2014-03-10 17:42:56 -07004196 }
Phil Burk00eeb322016-03-31 12:41:00 -07004197 updateAudioProfiles(device, output, profile->getAudioProfiles());
François Gaffie112b0af2015-11-19 16:13:25 +01004198 if (!profile->hasValidAudioProfile()) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004199 ALOGW("checkOutputsForDevice() missing param");
Eric Laurentd4692962014-05-05 18:13:44 -07004200 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07004201 output = AUDIO_IO_HANDLE_NONE;
François Gaffie112b0af2015-11-19 16:13:25 +01004202 } else if (profile->hasDynamicAudioProfile()) {
Eric Laurentd4692962014-05-05 18:13:44 -07004203 mpClientInterface->closeOutput(output);
Phil Burk702b1052016-03-02 16:38:26 -08004204 output = AUDIO_IO_HANDLE_NONE;
François Gaffie112b0af2015-11-19 16:13:25 +01004205 profile->pickAudioProfile(config.sample_rate, config.channel_mask, config.format);
Eric Laurentcf2c0212014-07-25 16:20:43 -07004206 config.offload_info.sample_rate = config.sample_rate;
4207 config.offload_info.channel_mask = config.channel_mask;
4208 config.offload_info.format = config.format;
Eric Laurent322b4d22015-04-03 15:57:54 -07004209 status = mpClientInterface->openOutput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07004210 &output,
4211 &config,
4212 &desc->mDevice,
4213 address,
4214 &desc->mLatency,
4215 desc->mFlags);
4216 if (status == NO_ERROR) {
4217 desc->mSamplingRate = config.sample_rate;
4218 desc->mChannelMask = config.channel_mask;
4219 desc->mFormat = config.format;
4220 } else {
4221 output = AUDIO_IO_HANDLE_NONE;
4222 }
Eric Laurentd4692962014-05-05 18:13:44 -07004223 }
4224
Eric Laurentcf2c0212014-07-25 16:20:43 -07004225 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07004226 addOutput(output, desc);
François Gaffie53615e22015-03-19 09:24:12 +01004227 if (device_distinguishes_on_address(device) && address != "0") {
François Gaffie036e1e92015-03-19 10:16:24 +01004228 sp<AudioPolicyMix> policyMix;
4229 if (mPolicyMixes.getAudioPolicyMix(address, policyMix) != NO_ERROR) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004230 ALOGE("checkOutputsForDevice() cannot find policy for address %s",
4231 address.string());
4232 }
François Gaffie036e1e92015-03-19 10:16:24 +01004233 policyMix->setOutput(desc);
Jean-Michel Trividacc06f2015-04-08 18:16:39 -07004234 desc->mPolicyMix = policyMix->getMix();
François Gaffie036e1e92015-03-19 10:16:24 +01004235
Eric Laurent87ffa392015-05-22 10:32:38 -07004236 } else if (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
4237 hasPrimaryOutput()) {
Eric Laurentc722f302014-12-10 11:21:49 -08004238 // no duplicated output for direct outputs and
4239 // outputs used by dynamic policy mixes
Eric Laurentcf2c0212014-07-25 16:20:43 -07004240 audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07004241
Eric Laurentd4692962014-05-05 18:13:44 -07004242 // set initial stream volume for device
Eric Laurentc75307b2015-03-17 15:29:32 -07004243 applyStreamVolumes(desc, device, 0, true);
Eric Laurente552edb2014-03-10 17:42:56 -07004244
Eric Laurentd4692962014-05-05 18:13:44 -07004245 //TODO: configure audio effect output stage here
4246
4247 // open a duplicating output thread for the new output and the primary output
Eric Laurentc75307b2015-03-17 15:29:32 -07004248 duplicatedOutput =
4249 mpClientInterface->openDuplicateOutput(output,
4250 mPrimaryOutput->mIoHandle);
Eric Laurentcf2c0212014-07-25 16:20:43 -07004251 if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07004252 // add duplicated output descriptor
Eric Laurentc75307b2015-03-17 15:29:32 -07004253 sp<SwAudioOutputDescriptor> dupOutputDesc =
4254 new SwAudioOutputDescriptor(NULL, mpClientInterface);
4255 dupOutputDesc->mOutput1 = mPrimaryOutput;
4256 dupOutputDesc->mOutput2 = desc;
Eric Laurentd4692962014-05-05 18:13:44 -07004257 dupOutputDesc->mSamplingRate = desc->mSamplingRate;
4258 dupOutputDesc->mFormat = desc->mFormat;
4259 dupOutputDesc->mChannelMask = desc->mChannelMask;
4260 dupOutputDesc->mLatency = desc->mLatency;
4261 addOutput(duplicatedOutput, dupOutputDesc);
Eric Laurentc75307b2015-03-17 15:29:32 -07004262 applyStreamVolumes(dupOutputDesc, device, 0, true);
Eric Laurentd4692962014-05-05 18:13:44 -07004263 } else {
4264 ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
Eric Laurentc75307b2015-03-17 15:29:32 -07004265 mPrimaryOutput->mIoHandle, output);
Eric Laurentd4692962014-05-05 18:13:44 -07004266 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01004267 removeOutput(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07004268 nextAudioPortGeneration();
Eric Laurentcf2c0212014-07-25 16:20:43 -07004269 output = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07004270 }
Eric Laurente552edb2014-03-10 17:42:56 -07004271 }
4272 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07004273 } else {
4274 output = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07004275 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07004276 if (output == AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07004277 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07004278 profiles.removeAt(profile_index);
4279 profile_index--;
4280 } else {
4281 outputs.add(output);
Paul McLean9080a4c2015-06-18 08:24:02 -07004282 // Load digital format info only for digital devices
4283 if (audio_device_is_digital(device)) {
4284 devDesc->importAudioPort(profile);
4285 }
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07004286
François Gaffie53615e22015-03-19 09:24:12 +01004287 if (device_distinguishes_on_address(device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004288 ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
4289 device, address.string());
Eric Laurentc75307b2015-03-17 15:29:32 -07004290 setOutputDevice(desc, device, true/*force*/, 0/*delay*/,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004291 NULL/*patch handle*/, address.string());
4292 }
Eric Laurente552edb2014-03-10 17:42:56 -07004293 ALOGV("checkOutputsForDevice(): adding output %d", output);
4294 }
4295 }
4296
4297 if (profiles.isEmpty()) {
4298 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
4299 return BAD_VALUE;
4300 }
Eric Laurentd4692962014-05-05 18:13:44 -07004301 } else { // Disconnect
Eric Laurente552edb2014-03-10 17:42:56 -07004302 // check if one opened output is not needed any more after disconnecting one device
4303 for (size_t i = 0; i < mOutputs.size(); i++) {
4304 desc = mOutputs.valueAt(i);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004305 if (!desc->isDuplicated()) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004306 // exact match on device
François Gaffie53615e22015-03-19 09:24:12 +01004307 if (device_distinguishes_on_address(device) &&
Eric Laurentc75307b2015-03-17 15:29:32 -07004308 (desc->supportedDevices() == device)) {
keunyoung3190e672014-12-30 13:00:52 -08004309 findIoHandlesByAddress(desc, device, address, outputs);
Eric Laurentc75307b2015-03-17 15:29:32 -07004310 } else if (!(desc->supportedDevices() & mAvailableOutputDevices.types())) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004311 ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
4312 mOutputs.keyAt(i));
4313 outputs.add(mOutputs.keyAt(i));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004314 }
Eric Laurente552edb2014-03-10 17:42:56 -07004315 }
4316 }
Eric Laurentd4692962014-05-05 18:13:44 -07004317 // Clear any profiles associated with the disconnected device.
Eric Laurente552edb2014-03-10 17:42:56 -07004318 for (size_t i = 0; i < mHwModules.size(); i++)
4319 {
4320 if (mHwModules[i]->mHandle == 0) {
4321 continue;
4322 }
4323 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
4324 {
Eric Laurent1c333e22014-05-20 10:48:17 -07004325 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004326 if (profile->supportDevice(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -07004327 ALOGV("checkOutputsForDevice(): "
4328 "clearing direct output profile %zu on module %zu", j, i);
François Gaffie112b0af2015-11-19 16:13:25 +01004329 profile->clearAudioProfiles();
Eric Laurente552edb2014-03-10 17:42:56 -07004330 }
4331 }
4332 }
4333 }
4334 return NO_ERROR;
4335}
4336
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004337status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& devDesc,
François Gaffie53615e22015-03-19 09:24:12 +01004338 audio_policy_dev_state_t state,
4339 SortedVector<audio_io_handle_t>& inputs,
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004340 const String8& address)
Eric Laurentd4692962014-05-05 18:13:44 -07004341{
Paul McLean9080a4c2015-06-18 08:24:02 -07004342 audio_devices_t device = devDesc->type();
Eric Laurent1f2f2232014-06-02 12:01:23 -07004343 sp<AudioInputDescriptor> desc;
Eric Laurentcc750d32015-06-25 11:48:20 -07004344
4345 if (audio_device_is_digital(device)) {
4346 // erase all current sample rates, formats and channel masks
Eric Laurent20eb3a42016-01-26 18:39:17 -08004347 devDesc->clearAudioProfiles();
Eric Laurentcc750d32015-06-25 11:48:20 -07004348 }
4349
Eric Laurentd4692962014-05-05 18:13:44 -07004350 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
4351 // first list already open inputs that can be routed to this device
4352 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4353 desc = mInputs.valueAt(input_index);
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004354 if (desc->mProfile->supportDevice(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -07004355 ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
4356 inputs.add(mInputs.keyAt(input_index));
4357 }
4358 }
4359
4360 // then look for input profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07004361 SortedVector< sp<IOProfile> > profiles;
Eric Laurentd4692962014-05-05 18:13:44 -07004362 for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
4363 {
4364 if (mHwModules[module_idx]->mHandle == 0) {
4365 continue;
4366 }
4367 for (size_t profile_index = 0;
4368 profile_index < mHwModules[module_idx]->mInputProfiles.size();
4369 profile_index++)
4370 {
Eric Laurent275e8e92014-11-30 15:14:47 -08004371 sp<IOProfile> profile = mHwModules[module_idx]->mInputProfiles[profile_index];
4372
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004373 if (profile->supportDevice(device)) {
François Gaffie53615e22015-03-19 09:24:12 +01004374 if (!device_distinguishes_on_address(device) ||
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004375 profile->supportDeviceAddress(address)) {
Eric Laurent275e8e92014-11-30 15:14:47 -08004376 profiles.add(profile);
4377 ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
4378 profile_index, module_idx);
4379 }
Eric Laurentd4692962014-05-05 18:13:44 -07004380 }
4381 }
4382 }
4383
4384 if (profiles.isEmpty() && inputs.isEmpty()) {
4385 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4386 return BAD_VALUE;
4387 }
4388
4389 // open inputs for matching profiles if needed. Direct inputs are also opened to
4390 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
4391 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
4392
Eric Laurent1c333e22014-05-20 10:48:17 -07004393 sp<IOProfile> profile = profiles[profile_index];
Eric Laurentd4692962014-05-05 18:13:44 -07004394 // nothing to do if one input is already opened for this profile
4395 size_t input_index;
4396 for (input_index = 0; input_index < mInputs.size(); input_index++) {
4397 desc = mInputs.valueAt(input_index);
4398 if (desc->mProfile == profile) {
Paul McLean9080a4c2015-06-18 08:24:02 -07004399 if (audio_device_is_digital(device)) {
4400 devDesc->importAudioPort(profile);
4401 }
Eric Laurentd4692962014-05-05 18:13:44 -07004402 break;
4403 }
4404 }
4405 if (input_index != mInputs.size()) {
4406 continue;
4407 }
4408
4409 ALOGV("opening input for device 0x%X with params %s", device, address.string());
4410 desc = new AudioInputDescriptor(profile);
4411 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07004412 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
4413 config.sample_rate = desc->mSamplingRate;
4414 config.channel_mask = desc->mChannelMask;
4415 config.format = desc->mFormat;
4416 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
Eric Laurent83efe1c2017-07-09 16:51:08 -07004417
4418 ALOGV("opening inputput for device %08x with params %s profile %p name %s",
4419 desc->mDevice, address.string(), profile.get(), profile->getName().string());
4420
Eric Laurent322b4d22015-04-03 15:57:54 -07004421 status_t status = mpClientInterface->openInput(profile->getModuleHandle(),
Eric Laurentcf2c0212014-07-25 16:20:43 -07004422 &input,
4423 &config,
4424 &desc->mDevice,
4425 address,
4426 AUDIO_SOURCE_MIC,
4427 AUDIO_INPUT_FLAG_NONE /*FIXME*/);
Eric Laurentd4692962014-05-05 18:13:44 -07004428
Eric Laurentcf2c0212014-07-25 16:20:43 -07004429 if (status == NO_ERROR) {
4430 desc->mSamplingRate = config.sample_rate;
4431 desc->mChannelMask = config.channel_mask;
4432 desc->mFormat = config.format;
Eric Laurentd4692962014-05-05 18:13:44 -07004433
Eric Laurentd4692962014-05-05 18:13:44 -07004434 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07004435 char *param = audio_device_address_to_parameter(device, address);
4436 mpClientInterface->setParameters(input, String8(param));
4437 free(param);
Eric Laurentd4692962014-05-05 18:13:44 -07004438 }
Phil Burk00eeb322016-03-31 12:41:00 -07004439 updateAudioProfiles(device, input, profile->getAudioProfiles());
François Gaffie112b0af2015-11-19 16:13:25 +01004440 if (!profile->hasValidAudioProfile()) {
Eric Laurentd4692962014-05-05 18:13:44 -07004441 ALOGW("checkInputsForDevice() direct input missing param");
4442 mpClientInterface->closeInput(input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07004443 input = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07004444 }
4445
4446 if (input != 0) {
4447 addInput(input, desc);
4448 }
4449 } // endif input != 0
4450
Eric Laurentcf2c0212014-07-25 16:20:43 -07004451 if (input == AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07004452 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
Eric Laurentd4692962014-05-05 18:13:44 -07004453 profiles.removeAt(profile_index);
4454 profile_index--;
4455 } else {
4456 inputs.add(input);
Paul McLean9080a4c2015-06-18 08:24:02 -07004457 if (audio_device_is_digital(device)) {
4458 devDesc->importAudioPort(profile);
4459 }
Eric Laurentd4692962014-05-05 18:13:44 -07004460 ALOGV("checkInputsForDevice(): adding input %d", input);
4461 }
4462 } // end scan profiles
4463
4464 if (profiles.isEmpty()) {
4465 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
4466 return BAD_VALUE;
4467 }
4468 } else {
4469 // Disconnect
4470 // check if one opened input is not needed any more after disconnecting one device
4471 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
4472 desc = mInputs.valueAt(input_index);
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004473 if (!(desc->mProfile->supportDevice(mAvailableInputDevices.types()))) {
Eric Laurentd4692962014-05-05 18:13:44 -07004474 ALOGV("checkInputsForDevice(): disconnecting adding input %d",
4475 mInputs.keyAt(input_index));
4476 inputs.add(mInputs.keyAt(input_index));
4477 }
4478 }
4479 // Clear any profiles associated with the disconnected device.
4480 for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
4481 if (mHwModules[module_index]->mHandle == 0) {
4482 continue;
4483 }
4484 for (size_t profile_index = 0;
4485 profile_index < mHwModules[module_index]->mInputProfiles.size();
4486 profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004487 sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
François Gaffiea8ecc2c2015-11-09 16:10:40 +01004488 if (profile->supportDevice(device)) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07004489 ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
Eric Laurentd4692962014-05-05 18:13:44 -07004490 profile_index, module_index);
François Gaffie112b0af2015-11-19 16:13:25 +01004491 profile->clearAudioProfiles();
Eric Laurentd4692962014-05-05 18:13:44 -07004492 }
4493 }
4494 }
4495 } // end disconnect
4496
4497 return NO_ERROR;
4498}
4499
4500
Eric Laurente0720872014-03-11 09:30:41 -07004501void AudioPolicyManager::closeOutput(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07004502{
4503 ALOGV("closeOutput(%d)", output);
4504
Eric Laurentc75307b2015-03-17 15:29:32 -07004505 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004506 if (outputDesc == NULL) {
4507 ALOGW("closeOutput() unknown output %d", output);
4508 return;
4509 }
François Gaffie036e1e92015-03-19 10:16:24 +01004510 mPolicyMixes.closeOutput(outputDesc);
Eric Laurent275e8e92014-11-30 15:14:47 -08004511
Eric Laurente552edb2014-03-10 17:42:56 -07004512 // look for duplicated outputs connected to the output being removed.
4513 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004514 sp<SwAudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07004515 if (dupOutputDesc->isDuplicated() &&
4516 (dupOutputDesc->mOutput1 == outputDesc ||
4517 dupOutputDesc->mOutput2 == outputDesc)) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004518 sp<AudioOutputDescriptor> outputDesc2;
Eric Laurente552edb2014-03-10 17:42:56 -07004519 if (dupOutputDesc->mOutput1 == outputDesc) {
4520 outputDesc2 = dupOutputDesc->mOutput2;
4521 } else {
4522 outputDesc2 = dupOutputDesc->mOutput1;
4523 }
4524 // As all active tracks on duplicated output will be deleted,
4525 // and as they were also referenced on the other output, the reference
4526 // count for their stream type must be adjusted accordingly on
4527 // the other output.
Eric Laurent3b73df72014-03-11 09:06:29 -07004528 for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
Eric Laurente552edb2014-03-10 17:42:56 -07004529 int refCount = dupOutputDesc->mRefCount[j];
Eric Laurent3b73df72014-03-11 09:06:29 -07004530 outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
Eric Laurente552edb2014-03-10 17:42:56 -07004531 }
4532 audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
4533 ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
4534
4535 mpClientInterface->closeOutput(duplicatedOutput);
François Gaffie53615e22015-03-19 09:24:12 +01004536 removeOutput(duplicatedOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07004537 }
4538 }
4539
Eric Laurent05b90f82014-08-27 15:32:29 -07004540 nextAudioPortGeneration();
4541
Jean-Michel Triviff155c62016-02-26 12:07:16 -08004542 ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
Eric Laurent05b90f82014-08-27 15:32:29 -07004543 if (index >= 0) {
4544 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
Glenn Kastenfcddb0b2016-07-08 17:19:25 -07004545 (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent05b90f82014-08-27 15:32:29 -07004546 mAudioPatches.removeItemsAt(index);
4547 mpClientInterface->onAudioPatchListUpdate();
4548 }
4549
Eric Laurente552edb2014-03-10 17:42:56 -07004550 AudioParameter param;
4551 param.add(String8("closing"), String8("true"));
4552 mpClientInterface->setParameters(output, param.toString());
4553
4554 mpClientInterface->closeOutput(output);
François Gaffie53615e22015-03-19 09:24:12 +01004555 removeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004556 mPreviousOutputs = mOutputs;
Eric Laurent05b90f82014-08-27 15:32:29 -07004557}
4558
4559void AudioPolicyManager::closeInput(audio_io_handle_t input)
4560{
4561 ALOGV("closeInput(%d)", input);
4562
4563 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
4564 if (inputDesc == NULL) {
4565 ALOGW("closeInput() unknown input %d", input);
4566 return;
4567 }
4568
Eric Laurent6a94d692014-05-20 11:18:06 -07004569 nextAudioPortGeneration();
Eric Laurent05b90f82014-08-27 15:32:29 -07004570
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08004571 ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
Eric Laurent05b90f82014-08-27 15:32:29 -07004572 if (index >= 0) {
4573 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
Glenn Kastenfcddb0b2016-07-08 17:19:25 -07004574 (void) /*status_t status*/ mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent05b90f82014-08-27 15:32:29 -07004575 mAudioPatches.removeItemsAt(index);
4576 mpClientInterface->onAudioPatchListUpdate();
4577 }
4578
4579 mpClientInterface->closeInput(input);
4580 mInputs.removeItem(input);
Eric Laurente552edb2014-03-10 17:42:56 -07004581}
4582
Eric Laurentc75307b2015-03-17 15:29:32 -07004583SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(
4584 audio_devices_t device,
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004585 const SwAudioOutputCollection& openOutputs)
Eric Laurente552edb2014-03-10 17:42:56 -07004586{
4587 SortedVector<audio_io_handle_t> outputs;
4588
4589 ALOGVV("getOutputsForDevice() device %04x", device);
4590 for (size_t i = 0; i < openOutputs.size(); i++) {
Eric Laurent37ddbb42016-08-10 16:19:14 -07004591 ALOGVV("output %zu isDuplicated=%d device=%04x",
Eric Laurent8c7e6da2015-04-21 17:37:00 -07004592 i, openOutputs.valueAt(i)->isDuplicated(),
4593 openOutputs.valueAt(i)->supportedDevices());
Eric Laurente552edb2014-03-10 17:42:56 -07004594 if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
4595 ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
4596 outputs.add(openOutputs.keyAt(i));
4597 }
4598 }
4599 return outputs;
4600}
4601
Eric Laurente0720872014-03-11 09:30:41 -07004602bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
François Gaffie53615e22015-03-19 09:24:12 +01004603 SortedVector<audio_io_handle_t>& outputs2)
Eric Laurente552edb2014-03-10 17:42:56 -07004604{
4605 if (outputs1.size() != outputs2.size()) {
4606 return false;
4607 }
4608 for (size_t i = 0; i < outputs1.size(); i++) {
4609 if (outputs1[i] != outputs2[i]) {
4610 return false;
4611 }
4612 }
4613 return true;
4614}
4615
Eric Laurente0720872014-03-11 09:30:41 -07004616void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
Eric Laurente552edb2014-03-10 17:42:56 -07004617{
4618 audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
4619 audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
4620 SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
4621 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
4622
Jean-Michel Trivife472e22014-12-16 14:23:13 -08004623 // also take into account external policy-related changes: add all outputs which are
4624 // associated with policies in the "before" and "after" output vectors
4625 ALOGVV("checkOutputForStrategy(): policy related outputs");
4626 for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004627 const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
Jean-Michel Trivife472e22014-12-16 14:23:13 -08004628 if (desc != 0 && desc->mPolicyMix != NULL) {
4629 srcOutputs.add(desc->mIoHandle);
4630 ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
4631 }
4632 }
4633 for (size_t i = 0 ; i < mOutputs.size() ; i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004634 const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Jean-Michel Trivife472e22014-12-16 14:23:13 -08004635 if (desc != 0 && desc->mPolicyMix != NULL) {
4636 dstOutputs.add(desc->mIoHandle);
4637 ALOGVV(" new outputs: adding %d", desc->mIoHandle);
4638 }
4639 }
4640
Eric Laurente552edb2014-03-10 17:42:56 -07004641 if (!vectorsEqual(srcOutputs,dstOutputs)) {
4642 ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
4643 strategy, srcOutputs[0], dstOutputs[0]);
4644 // mute strategy while moving tracks from one output to another
4645 for (size_t i = 0; i < srcOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004646 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
François Gaffiead3183e2015-03-18 16:55:35 +01004647 if (isStrategyActive(desc, strategy)) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004648 setStrategyMute(strategy, true, desc);
4649 setStrategyMute(strategy, false, desc, MUTE_TIME_MS, newDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07004650 }
Eric Laurentd60560a2015-04-10 11:31:20 -07004651 sp<AudioSourceDescriptor> source =
4652 getSourceForStrategyOnOutput(srcOutputs[i], strategy);
4653 if (source != 0){
4654 connectAudioSource(source);
4655 }
Eric Laurente552edb2014-03-10 17:42:56 -07004656 }
4657
4658 // Move effects associated to this strategy from previous output to new output
4659 if (strategy == STRATEGY_MEDIA) {
Eric Laurent36829f92017-04-07 19:04:42 -07004660 selectOutputForMusicEffects();
Eric Laurente552edb2014-03-10 17:42:56 -07004661 }
4662 // Move tracks associated to this strategy from previous output to new output
Eric Laurent794fde22016-03-11 09:50:45 -08004663 for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
Eric Laurent3b73df72014-03-11 09:06:29 -07004664 if (getStrategy((audio_stream_type_t)i) == strategy) {
4665 mpClientInterface->invalidateStream((audio_stream_type_t)i);
Eric Laurente552edb2014-03-10 17:42:56 -07004666 }
4667 }
4668 }
4669}
4670
Eric Laurente0720872014-03-11 09:30:41 -07004671void AudioPolicyManager::checkOutputForAllStrategies()
Eric Laurente552edb2014-03-10 17:42:56 -07004672{
François Gaffie2110e042015-03-24 08:41:51 +01004673 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05004674 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07004675 checkOutputForStrategy(STRATEGY_PHONE);
François Gaffie2110e042015-03-24 08:41:51 +01004676 if (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)
Jon Eklund966095e2014-09-09 15:39:49 -05004677 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
Eric Laurente552edb2014-03-10 17:42:56 -07004678 checkOutputForStrategy(STRATEGY_SONIFICATION);
4679 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
Eric Laurent223fd5c2014-11-11 13:43:36 -08004680 checkOutputForStrategy(STRATEGY_ACCESSIBILITY);
Eric Laurente552edb2014-03-10 17:42:56 -07004681 checkOutputForStrategy(STRATEGY_MEDIA);
4682 checkOutputForStrategy(STRATEGY_DTMF);
Eric Laurent223fd5c2014-11-11 13:43:36 -08004683 checkOutputForStrategy(STRATEGY_REROUTING);
Eric Laurente552edb2014-03-10 17:42:56 -07004684}
4685
Eric Laurente0720872014-03-11 09:30:41 -07004686void AudioPolicyManager::checkA2dpSuspend()
Eric Laurente552edb2014-03-10 17:42:56 -07004687{
François Gaffie53615e22015-03-19 09:24:12 +01004688 audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput();
Aniket Kumar Lata32371762018-01-31 20:24:23 -08004689 if (a2dpOutput == 0 || mOutputs.isA2dpOffloadedOnPrimary()) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004690 mA2dpSuspended = false;
Eric Laurente552edb2014-03-10 17:42:56 -07004691 return;
4692 }
4693
Eric Laurent3a4311c2014-03-17 12:00:47 -07004694 bool isScoConnected =
Eric Laurentddbc6652014-11-13 15:13:44 -08004695 ((mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET &
4696 ~AUDIO_DEVICE_BIT_IN) != 0) ||
4697 ((mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_ALL_SCO) != 0);
Eric Laurentf732e072016-08-03 19:30:28 -07004698
4699 // if suspended, restore A2DP output if:
4700 // ((SCO device is NOT connected) ||
4701 // ((forced usage communication is NOT SCO) && (forced usage for record is NOT SCO) &&
4702 // (phone state is NOT in call) && (phone state is NOT ringing)))
Eric Laurente552edb2014-03-10 17:42:56 -07004703 //
Eric Laurentf732e072016-08-03 19:30:28 -07004704 // if not suspended, suspend A2DP output if:
4705 // (SCO device is connected) &&
4706 // ((forced usage for communication is SCO) || (forced usage for record is SCO) ||
4707 // ((phone state is in call) || (phone state is ringing)))
Eric Laurente552edb2014-03-10 17:42:56 -07004708 //
4709 if (mA2dpSuspended) {
Eric Laurentf732e072016-08-03 19:30:28 -07004710 if (!isScoConnected ||
4711 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) !=
4712 AUDIO_POLICY_FORCE_BT_SCO) &&
4713 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) !=
4714 AUDIO_POLICY_FORCE_BT_SCO) &&
4715 (mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) &&
François Gaffie2110e042015-03-24 08:41:51 +01004716 (mEngine->getPhoneState() != AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07004717
4718 mpClientInterface->restoreOutput(a2dpOutput);
4719 mA2dpSuspended = false;
4720 }
4721 } else {
Eric Laurentf732e072016-08-03 19:30:28 -07004722 if (isScoConnected &&
4723 ((mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ==
4724 AUDIO_POLICY_FORCE_BT_SCO) ||
4725 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) ==
4726 AUDIO_POLICY_FORCE_BT_SCO) ||
4727 (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL) ||
François Gaffie2110e042015-03-24 08:41:51 +01004728 (mEngine->getPhoneState() == AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07004729
4730 mpClientInterface->suspendOutput(a2dpOutput);
4731 mA2dpSuspended = true;
4732 }
4733 }
4734}
4735
Eric Laurentc75307b2015-03-17 15:29:32 -07004736audio_devices_t AudioPolicyManager::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
4737 bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07004738{
4739 audio_devices_t device = AUDIO_DEVICE_NONE;
4740
Jean-Michel Triviff155c62016-02-26 12:07:16 -08004741 ssize_t index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07004742 if (index >= 0) {
4743 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4744 if (patchDesc->mUid != mUidCached) {
4745 ALOGV("getNewOutputDevice() device %08x forced by patch %d",
Jean-Michel Triviff155c62016-02-26 12:07:16 -08004746 outputDesc->device(), outputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07004747 return outputDesc->device();
4748 }
4749 }
4750
Eric Laurente552edb2014-03-10 17:42:56 -07004751 // check the following by order of priority to request a routing change if necessary:
Jon Eklund966095e2014-09-09 15:39:49 -05004752 // 1: the strategy enforced audible is active and enforced on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07004753 // use device for strategy enforced audible
4754 // 2: we are in call or the strategy phone is active on the output:
4755 // use device for strategy phone
Jean-Michel Trivi178683b2017-08-30 18:07:06 -07004756 // 3: the strategy sonification is active on the output:
Jean-Michel Trivi5de234b2015-07-21 11:42:02 -07004757 // use device for strategy sonification
Jean-Michel Trivi178683b2017-08-30 18:07:06 -07004758 // 4: the strategy for enforced audible is active but not enforced on the output:
4759 // use the device for strategy enforced audible
Eric Laurent28d09f02016-03-08 10:43:05 -08004760 // 5: the strategy accessibility is active on the output:
4761 // use device for strategy accessibility
Jean-Michel Trivi5de234b2015-07-21 11:42:02 -07004762 // 6: the strategy "respectful" sonification is active on the output:
4763 // use device for strategy "respectful" sonification
Eric Laurent223fd5c2014-11-11 13:43:36 -08004764 // 7: the strategy media is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07004765 // use device for strategy media
Eric Laurent223fd5c2014-11-11 13:43:36 -08004766 // 8: the strategy DTMF is active on the output:
Eric Laurente552edb2014-03-10 17:42:56 -07004767 // use device for strategy DTMF
Eric Laurent223fd5c2014-11-11 13:43:36 -08004768 // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004769 // use device for strategy t-t-s
François Gaffiead3183e2015-03-18 16:55:35 +01004770 if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01004771 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
Eric Laurente552edb2014-03-10 17:42:56 -07004772 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
4773 } else if (isInCall() ||
François Gaffiead3183e2015-03-18 16:55:35 +01004774 isStrategyActive(outputDesc, STRATEGY_PHONE)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004775 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004776 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004777 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
Jean-Michel Trivi178683b2017-08-30 18:07:06 -07004778 } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
4779 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
Eric Laurent28d09f02016-03-08 10:43:05 -08004780 } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
4781 device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004782 } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004783 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004784 } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004785 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004786 } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004787 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004788 } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004789 device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
François Gaffiead3183e2015-03-18 16:55:35 +01004790 } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
Eric Laurent223fd5c2014-11-11 13:43:36 -08004791 device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
Eric Laurente552edb2014-03-10 17:42:56 -07004792 }
4793
Eric Laurent1c333e22014-05-20 10:48:17 -07004794 ALOGV("getNewOutputDevice() selected device %x", device);
4795 return device;
4796}
4797
Eric Laurentfb66dd92016-01-28 18:32:03 -08004798audio_devices_t AudioPolicyManager::getNewInputDevice(const sp<AudioInputDescriptor>& inputDesc)
Eric Laurent1c333e22014-05-20 10:48:17 -07004799{
Eric Laurentfb66dd92016-01-28 18:32:03 -08004800 audio_devices_t device = AUDIO_DEVICE_NONE;
Eric Laurent6a94d692014-05-20 11:18:06 -07004801
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08004802 ssize_t index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07004803 if (index >= 0) {
4804 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4805 if (patchDesc->mUid != mUidCached) {
4806 ALOGV("getNewInputDevice() device %08x forced by patch %d",
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08004807 inputDesc->mDevice, inputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07004808 return inputDesc->mDevice;
4809 }
4810 }
4811
Eric Laurentfb66dd92016-01-28 18:32:03 -08004812 audio_source_t source = inputDesc->getHighestPrioritySource(true /*activeOnly*/);
4813 if (isInCall()) {
4814 device = getDeviceAndMixForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
4815 } else if (source != AUDIO_SOURCE_DEFAULT) {
4816 device = getDeviceAndMixForInputSource(source);
4817 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004818
Eric Laurente552edb2014-03-10 17:42:56 -07004819 return device;
4820}
4821
Eric Laurent794fde22016-03-11 09:50:45 -08004822bool AudioPolicyManager::streamsMatchForvolume(audio_stream_type_t stream1,
4823 audio_stream_type_t stream2) {
Jean-Michel Trivi99bb2f92016-11-23 15:52:07 -08004824 return (stream1 == stream2);
Eric Laurent28d09f02016-03-08 10:43:05 -08004825}
4826
Eric Laurente0720872014-03-11 09:30:41 -07004827uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004828 return (uint32_t)getStrategy(stream);
4829}
4830
Eric Laurente0720872014-03-11 09:30:41 -07004831audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004832 // By checking the range of stream before calling getStrategy, we avoid
4833 // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
4834 // and then return STRATEGY_MEDIA, but we want to return the empty set.
Eric Laurent223fd5c2014-11-11 13:43:36 -08004835 if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_PUBLIC_CNT) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004836 return AUDIO_DEVICE_NONE;
4837 }
Eric Laurent28d09f02016-03-08 10:43:05 -08004838 audio_devices_t devices = AUDIO_DEVICE_NONE;
Eric Laurent794fde22016-03-11 09:50:45 -08004839 for (int curStream = 0; curStream < AUDIO_STREAM_FOR_POLICY_CNT; curStream++) {
4840 if (!streamsMatchForvolume(stream, (audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08004841 continue;
Eric Laurent6a94d692014-05-20 11:18:06 -07004842 }
Eric Laurent794fde22016-03-11 09:50:45 -08004843 routing_strategy curStrategy = getStrategy((audio_stream_type_t)curStream);
Eric Laurent28d09f02016-03-08 10:43:05 -08004844 audio_devices_t curDevices =
Eric Laurent447a87b2016-07-07 17:32:10 -07004845 getDeviceForStrategy((routing_strategy)curStrategy, false /*fromCache*/);
Eric Laurent28d09f02016-03-08 10:43:05 -08004846 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(curDevices, mOutputs);
4847 for (size_t i = 0; i < outputs.size(); i++) {
4848 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurent794fde22016-03-11 09:50:45 -08004849 if (outputDesc->isStreamActive((audio_stream_type_t)curStream)) {
Eric Laurent28d09f02016-03-08 10:43:05 -08004850 curDevices |= outputDesc->device();
4851 }
4852 }
4853 devices |= curDevices;
Eric Laurente552edb2014-03-10 17:42:56 -07004854 }
Jon Eklund11c9fb12014-06-23 14:47:03 -05004855
4856 /*Filter SPEAKER_SAFE out of results, as AudioService doesn't know about it
4857 and doesn't really need to.*/
4858 if (devices & AUDIO_DEVICE_OUT_SPEAKER_SAFE) {
4859 devices |= AUDIO_DEVICE_OUT_SPEAKER;
4860 devices &= ~AUDIO_DEVICE_OUT_SPEAKER_SAFE;
4861 }
Eric Laurente552edb2014-03-10 17:42:56 -07004862 return devices;
4863}
4864
François Gaffie2110e042015-03-24 08:41:51 +01004865routing_strategy AudioPolicyManager::getStrategy(audio_stream_type_t stream) const
4866{
Eric Laurent223fd5c2014-11-11 13:43:36 -08004867 ALOG_ASSERT(stream != AUDIO_STREAM_PATCH,"getStrategy() called for AUDIO_STREAM_PATCH");
François Gaffie2110e042015-03-24 08:41:51 +01004868 return mEngine->getStrategyForStream(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004869}
4870
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004871uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
4872 // flags to strategy mapping
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004873 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
4874 return (uint32_t) STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
4875 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004876 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
4877 return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
4878 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004879 // usage to strategy mapping
François Gaffie2110e042015-03-24 08:41:51 +01004880 return static_cast<uint32_t>(mEngine->getStrategyForUsage(attr->usage));
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07004881}
4882
Eric Laurente0720872014-03-11 09:30:41 -07004883void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07004884 switch(stream) {
Eric Laurent3b73df72014-03-11 09:06:29 -07004885 case AUDIO_STREAM_MUSIC:
Eric Laurente552edb2014-03-10 17:42:56 -07004886 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
4887 updateDevicesAndOutputs();
4888 break;
4889 default:
4890 break;
4891 }
4892}
4893
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004894uint32_t AudioPolicyManager::handleEventForBeacon(int event) {
Eric Laurent9459fb02015-08-12 18:36:32 -07004895
4896 // skip beacon mute management if a dedicated TTS output is available
4897 if (mTtsOutputAvailable) {
4898 return 0;
4899 }
4900
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004901 switch(event) {
4902 case STARTING_OUTPUT:
4903 mBeaconMuteRefCount++;
4904 break;
4905 case STOPPING_OUTPUT:
4906 if (mBeaconMuteRefCount > 0) {
4907 mBeaconMuteRefCount--;
4908 }
4909 break;
4910 case STARTING_BEACON:
4911 mBeaconPlayingRefCount++;
4912 break;
4913 case STOPPING_BEACON:
4914 if (mBeaconPlayingRefCount > 0) {
4915 mBeaconPlayingRefCount--;
4916 }
4917 break;
4918 }
4919
4920 if (mBeaconMuteRefCount > 0) {
4921 // any playback causes beacon to be muted
4922 return setBeaconMute(true);
4923 } else {
4924 // no other playback: unmute when beacon starts playing, mute when it stops
4925 return setBeaconMute(mBeaconPlayingRefCount == 0);
4926 }
4927}
4928
4929uint32_t AudioPolicyManager::setBeaconMute(bool mute) {
4930 ALOGV("setBeaconMute(%d) mBeaconMuteRefCount=%d mBeaconPlayingRefCount=%d",
4931 mute, mBeaconMuteRefCount, mBeaconPlayingRefCount);
4932 // keep track of muted state to avoid repeating mute/unmute operations
4933 if (mBeaconMuted != mute) {
4934 // mute/unmute AUDIO_STREAM_TTS on all outputs
4935 ALOGV("\t muting %d", mute);
4936 uint32_t maxLatency = 0;
4937 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc75307b2015-03-17 15:29:32 -07004938 sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004939 setStreamMute(AUDIO_STREAM_TTS, mute/*on*/,
Eric Laurentc75307b2015-03-17 15:29:32 -07004940 desc,
Jean-Michel Trivid9cfeb42014-09-22 16:51:34 -07004941 0 /*delay*/, AUDIO_DEVICE_NONE);
4942 const uint32_t latency = desc->latency() * 2;
4943 if (latency > maxLatency) {
4944 maxLatency = latency;
4945 }
4946 }
4947 mBeaconMuted = mute;
4948 return maxLatency;
4949 }
4950 return 0;
4951}
4952
Eric Laurente0720872014-03-11 09:30:41 -07004953audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
François Gaffie53615e22015-03-19 09:24:12 +01004954 bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07004955{
Paul McLeanaa981192015-03-21 09:55:15 -07004956 // Routing
4957 // see if we have an explicit route
4958 // scan the whole RouteMap, for each entry, convert the stream type to a strategy
4959 // (getStrategy(stream)).
4960 // if the strategy from the stream type in the RouteMap is the same as the argument above,
Eric Laurentad2e7b92017-09-14 20:06:42 -07004961 // and activity count is non-zero and the device in the route descriptor is available
4962 // then select this device.
Paul McLeanaa981192015-03-21 09:55:15 -07004963 for (size_t routeIndex = 0; routeIndex < mOutputRoutes.size(); routeIndex++) {
4964 sp<SessionRoute> route = mOutputRoutes.valueAt(routeIndex);
Eric Laurent28d09f02016-03-08 10:43:05 -08004965 routing_strategy routeStrategy = getStrategy(route->mStreamType);
Eric Laurentad2e7b92017-09-14 20:06:42 -07004966 if ((routeStrategy == strategy) && route->isActive() &&
4967 (mAvailableOutputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
Paul McLeanaa981192015-03-21 09:55:15 -07004968 return route->mDeviceDescriptor->type();
4969 }
4970 }
4971
Eric Laurente552edb2014-03-10 17:42:56 -07004972 if (fromCache) {
4973 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
4974 strategy, mDeviceForStrategy[strategy]);
4975 return mDeviceForStrategy[strategy];
4976 }
François Gaffie2110e042015-03-24 08:41:51 +01004977 return mEngine->getDeviceForStrategy(strategy);
Eric Laurente552edb2014-03-10 17:42:56 -07004978}
4979
Eric Laurente0720872014-03-11 09:30:41 -07004980void AudioPolicyManager::updateDevicesAndOutputs()
Eric Laurente552edb2014-03-10 17:42:56 -07004981{
4982 for (int i = 0; i < NUM_STRATEGIES; i++) {
4983 mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4984 }
4985 mPreviousOutputs = mOutputs;
4986}
4987
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07004988uint32_t AudioPolicyManager::checkDeviceMuteStrategies(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004989 audio_devices_t prevDevice,
4990 uint32_t delayMs)
4991{
4992 // mute/unmute strategies using an incompatible device combination
4993 // if muting, wait for the audio in pcm buffer to be drained before proceeding
4994 // if unmuting, unmute only after the specified delay
4995 if (outputDesc->isDuplicated()) {
4996 return 0;
4997 }
4998
4999 uint32_t muteWaitMs = 0;
5000 audio_devices_t device = outputDesc->device();
Eric Laurent3b73df72014-03-11 09:06:29 -07005001 bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
Eric Laurente552edb2014-03-10 17:42:56 -07005002
5003 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
5004 audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
Eric Laurentc75307b2015-03-17 15:29:32 -07005005 curDevice = curDevice & outputDesc->supportedDevices();
Eric Laurente552edb2014-03-10 17:42:56 -07005006 bool mute = shouldMute && (curDevice & device) && (curDevice != device);
5007 bool doMute = false;
5008
5009 if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
5010 doMute = true;
5011 outputDesc->mStrategyMutedByDevice[i] = true;
5012 } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
5013 doMute = true;
5014 outputDesc->mStrategyMutedByDevice[i] = false;
5015 }
Eric Laurent99401132014-05-07 19:48:15 -07005016 if (doMute) {
Eric Laurente552edb2014-03-10 17:42:56 -07005017 for (size_t j = 0; j < mOutputs.size(); j++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07005018 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
Eric Laurente552edb2014-03-10 17:42:56 -07005019 // skip output if it does not share any device with current output
5020 if ((desc->supportedDevices() & outputDesc->supportedDevices())
5021 == AUDIO_DEVICE_NONE) {
5022 continue;
5023 }
Eric Laurent37ddbb42016-08-10 16:19:14 -07005024 ALOGVV("checkDeviceMuteStrategies() %s strategy %zu (curDevice %04x)",
Eric Laurentc75307b2015-03-17 15:29:32 -07005025 mute ? "muting" : "unmuting", i, curDevice);
5026 setStrategyMute((routing_strategy)i, mute, desc, mute ? 0 : delayMs);
François Gaffiead3183e2015-03-18 16:55:35 +01005027 if (isStrategyActive(desc, (routing_strategy)i)) {
Eric Laurent99401132014-05-07 19:48:15 -07005028 if (mute) {
5029 // FIXME: should not need to double latency if volume could be applied
5030 // immediately by the audioflinger mixer. We must account for the delay
5031 // between now and the next time the audioflinger thread for this output
5032 // will process a buffer (which corresponds to one buffer size,
5033 // usually 1/2 or 1/4 of the latency).
5034 if (muteWaitMs < desc->latency() * 2) {
5035 muteWaitMs = desc->latency() * 2;
Eric Laurente552edb2014-03-10 17:42:56 -07005036 }
5037 }
5038 }
5039 }
5040 }
5041 }
5042
Eric Laurent99401132014-05-07 19:48:15 -07005043 // temporary mute output if device selection changes to avoid volume bursts due to
5044 // different per device volumes
5045 if (outputDesc->isActive() && (device != prevDevice)) {
Eric Laurentdc462862016-07-19 12:29:53 -07005046 uint32_t tempMuteWaitMs = outputDesc->latency() * 2;
5047 // temporary mute duration is conservatively set to 4 times the reported latency
5048 uint32_t tempMuteDurationMs = outputDesc->latency() * 4;
5049 if (muteWaitMs < tempMuteWaitMs) {
5050 muteWaitMs = tempMuteWaitMs;
Eric Laurent99401132014-05-07 19:48:15 -07005051 }
Eric Laurentdc462862016-07-19 12:29:53 -07005052
Eric Laurent99401132014-05-07 19:48:15 -07005053 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
François Gaffiead3183e2015-03-18 16:55:35 +01005054 if (isStrategyActive(outputDesc, (routing_strategy)i)) {
Eric Laurentdc462862016-07-19 12:29:53 -07005055 // make sure that we do not start the temporary mute period too early in case of
5056 // delayed device change
5057 setStrategyMute((routing_strategy)i, true, outputDesc, delayMs);
Eric Laurentc75307b2015-03-17 15:29:32 -07005058 setStrategyMute((routing_strategy)i, false, outputDesc,
Eric Laurentdc462862016-07-19 12:29:53 -07005059 delayMs + tempMuteDurationMs, device);
Eric Laurent99401132014-05-07 19:48:15 -07005060 }
5061 }
5062 }
5063
Eric Laurente552edb2014-03-10 17:42:56 -07005064 // wait for the PCM output buffers to empty before proceeding with the rest of the command
5065 if (muteWaitMs > delayMs) {
5066 muteWaitMs -= delayMs;
5067 usleep(muteWaitMs * 1000);
5068 return muteWaitMs;
5069 }
5070 return 0;
5071}
5072
Eric Laurentc75307b2015-03-17 15:29:32 -07005073uint32_t AudioPolicyManager::setOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07005074 audio_devices_t device,
5075 bool force,
Eric Laurent6a94d692014-05-20 11:18:06 -07005076 int delayMs,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07005077 audio_patch_handle_t *patchHandle,
5078 const char* address)
Eric Laurente552edb2014-03-10 17:42:56 -07005079{
Eric Laurentc75307b2015-03-17 15:29:32 -07005080 ALOGV("setOutputDevice() device %04x delayMs %d", device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07005081 AudioParameter param;
5082 uint32_t muteWaitMs;
5083
5084 if (outputDesc->isDuplicated()) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005085 muteWaitMs = setOutputDevice(outputDesc->subOutput1(), device, force, delayMs);
5086 muteWaitMs += setOutputDevice(outputDesc->subOutput2(), device, force, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07005087 return muteWaitMs;
5088 }
5089 // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
5090 // output profile
Eric Laurentc75307b2015-03-17 15:29:32 -07005091 if ((device != AUDIO_DEVICE_NONE) &&
5092 ((device & outputDesc->supportedDevices()) == 0)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005093 return 0;
5094 }
5095
5096 // filter devices according to output selected
Eric Laurentc75307b2015-03-17 15:29:32 -07005097 device = (audio_devices_t)(device & outputDesc->supportedDevices());
Eric Laurente552edb2014-03-10 17:42:56 -07005098
5099 audio_devices_t prevDevice = outputDesc->mDevice;
5100
Paul McLeanaa981192015-03-21 09:55:15 -07005101 ALOGV("setOutputDevice() prevDevice 0x%04x", prevDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07005102
5103 if (device != AUDIO_DEVICE_NONE) {
5104 outputDesc->mDevice = device;
5105 }
5106 muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
5107
5108 // Do not change the routing if:
Eric Laurentb80a2a82014-10-27 16:07:59 -07005109 // the requested device is AUDIO_DEVICE_NONE
5110 // OR the requested device is the same as current device
5111 // AND force is not specified
5112 // AND the output is connected by a valid audio patch.
Eric Laurente552edb2014-03-10 17:42:56 -07005113 // Doing this check here allows the caller to call setOutputDevice() without conditions
Paul McLeanaa981192015-03-21 09:55:15 -07005114 if ((device == AUDIO_DEVICE_NONE || device == prevDevice) &&
5115 !force &&
Jean-Michel Triviff155c62016-02-26 12:07:16 -08005116 outputDesc->getPatchHandle() != 0) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005117 ALOGV("setOutputDevice() setting same device 0x%04x or null device", device);
Eric Laurente552edb2014-03-10 17:42:56 -07005118 return muteWaitMs;
5119 }
5120
5121 ALOGV("setOutputDevice() changing device");
Eric Laurent1c333e22014-05-20 10:48:17 -07005122
Eric Laurente552edb2014-03-10 17:42:56 -07005123 // do the routing
Eric Laurent1c333e22014-05-20 10:48:17 -07005124 if (device == AUDIO_DEVICE_NONE) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005125 resetOutputDevice(outputDesc, delayMs, NULL);
Eric Laurent1c333e22014-05-20 10:48:17 -07005126 } else {
Eric Laurentc40d9692016-04-13 19:14:13 -07005127 DeviceVector deviceList;
5128 if ((address == NULL) || (strlen(address) == 0)) {
5129 deviceList = mAvailableOutputDevices.getDevicesFromType(device);
5130 } else {
5131 deviceList = mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
5132 }
5133
Eric Laurent1c333e22014-05-20 10:48:17 -07005134 if (!deviceList.isEmpty()) {
5135 struct audio_patch patch;
5136 outputDesc->toAudioPortConfig(&patch.sources[0]);
5137 patch.num_sources = 1;
5138 patch.num_sinks = 0;
5139 for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
5140 deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
Eric Laurent1c333e22014-05-20 10:48:17 -07005141 patch.num_sinks++;
5142 }
Eric Laurent6a94d692014-05-20 11:18:06 -07005143 ssize_t index;
5144 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
5145 index = mAudioPatches.indexOfKey(*patchHandle);
5146 } else {
Jean-Michel Triviff155c62016-02-26 12:07:16 -08005147 index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07005148 }
5149 sp< AudioPatch> patchDesc;
5150 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
5151 if (index >= 0) {
5152 patchDesc = mAudioPatches.valueAt(index);
5153 afPatchHandle = patchDesc->mAfPatchHandle;
5154 }
5155
Eric Laurent1c333e22014-05-20 10:48:17 -07005156 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07005157 &afPatchHandle,
5158 delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07005159 ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
5160 "num_sources %d num_sinks %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07005161 status, afPatchHandle, patch.num_sources, patch.num_sinks);
Eric Laurent1c333e22014-05-20 10:48:17 -07005162 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07005163 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01005164 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07005165 addAudioPatch(patchDesc->mHandle, patchDesc);
5166 } else {
5167 patchDesc->mPatch = patch;
5168 }
5169 patchDesc->mAfPatchHandle = afPatchHandle;
Eric Laurent6a94d692014-05-20 11:18:06 -07005170 if (patchHandle) {
5171 *patchHandle = patchDesc->mHandle;
5172 }
Jean-Michel Triviff155c62016-02-26 12:07:16 -08005173 outputDesc->setPatchHandle(patchDesc->mHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07005174 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07005175 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07005176 }
5177 }
bryant_liuf5e7e792014-08-19 20:07:05 +08005178
5179 // inform all input as well
5180 for (size_t i = 0; i < mInputs.size(); i++) {
5181 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
François Gaffie53615e22015-03-19 09:24:12 +01005182 if (!is_virtual_input_device(inputDescriptor->mDevice)) {
bryant_liuf5e7e792014-08-19 20:07:05 +08005183 AudioParameter inputCmd = AudioParameter();
5184 ALOGV("%s: inform input %d of device:%d", __func__,
5185 inputDescriptor->mIoHandle, device);
5186 inputCmd.addInt(String8(AudioParameter::keyRouting),device);
5187 mpClientInterface->setParameters(inputDescriptor->mIoHandle,
5188 inputCmd.toString(),
5189 delayMs);
5190 }
5191 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005192 }
Eric Laurente552edb2014-03-10 17:42:56 -07005193
5194 // update stream volumes according to new device
Eric Laurentc75307b2015-03-17 15:29:32 -07005195 applyStreamVolumes(outputDesc, device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07005196
5197 return muteWaitMs;
5198}
5199
Eric Laurentc75307b2015-03-17 15:29:32 -07005200status_t AudioPolicyManager::resetOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
Eric Laurent6a94d692014-05-20 11:18:06 -07005201 int delayMs,
5202 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07005203{
Eric Laurent6a94d692014-05-20 11:18:06 -07005204 ssize_t index;
5205 if (patchHandle) {
5206 index = mAudioPatches.indexOfKey(*patchHandle);
5207 } else {
Jean-Michel Triviff155c62016-02-26 12:07:16 -08005208 index = mAudioPatches.indexOfKey(outputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07005209 }
5210 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07005211 return INVALID_OPERATION;
5212 }
Eric Laurent6a94d692014-05-20 11:18:06 -07005213 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
5214 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07005215 ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
Glenn Kastena13cde92016-03-28 15:26:02 -07005216 outputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
Eric Laurent6a94d692014-05-20 11:18:06 -07005217 removeAudioPatch(patchDesc->mHandle);
5218 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07005219 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07005220 return status;
5221}
5222
5223status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
5224 audio_devices_t device,
Eric Laurent6a94d692014-05-20 11:18:06 -07005225 bool force,
5226 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07005227{
5228 status_t status = NO_ERROR;
5229
Eric Laurent1f2f2232014-06-02 12:01:23 -07005230 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07005231 if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
5232 inputDesc->mDevice = device;
5233
5234 DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
5235 if (!deviceList.isEmpty()) {
5236 struct audio_patch patch;
5237 inputDesc->toAudioPortConfig(&patch.sinks[0]);
Eric Laurentdaf92cc2014-07-22 15:36:10 -07005238 // AUDIO_SOURCE_HOTWORD is for internal use only:
5239 // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07005240 if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
Eric Laurent599c7582015-12-07 18:05:55 -08005241 !inputDesc->isSoundTrigger()) {
Eric Laurentdaf92cc2014-07-22 15:36:10 -07005242 patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
5243 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005244 patch.num_sinks = 1;
5245 //only one input device for now
5246 deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
Eric Laurent1c333e22014-05-20 10:48:17 -07005247 patch.num_sources = 1;
Eric Laurent6a94d692014-05-20 11:18:06 -07005248 ssize_t index;
5249 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
5250 index = mAudioPatches.indexOfKey(*patchHandle);
5251 } else {
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08005252 index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07005253 }
5254 sp< AudioPatch> patchDesc;
5255 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
5256 if (index >= 0) {
5257 patchDesc = mAudioPatches.valueAt(index);
5258 afPatchHandle = patchDesc->mAfPatchHandle;
5259 }
5260
Eric Laurent1c333e22014-05-20 10:48:17 -07005261 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07005262 &afPatchHandle,
Eric Laurent1c333e22014-05-20 10:48:17 -07005263 0);
5264 ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07005265 status, afPatchHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -07005266 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07005267 if (index < 0) {
François Gaffie98cc1912015-03-18 17:52:40 +01005268 patchDesc = new AudioPatch(&patch, mUidCached);
Eric Laurent6a94d692014-05-20 11:18:06 -07005269 addAudioPatch(patchDesc->mHandle, patchDesc);
5270 } else {
5271 patchDesc->mPatch = patch;
5272 }
5273 patchDesc->mAfPatchHandle = afPatchHandle;
Eric Laurent6a94d692014-05-20 11:18:06 -07005274 if (patchHandle) {
5275 *patchHandle = patchDesc->mHandle;
5276 }
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08005277 inputDesc->setPatchHandle(patchDesc->mHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07005278 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07005279 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07005280 }
5281 }
5282 }
5283 return status;
5284}
5285
Eric Laurent6a94d692014-05-20 11:18:06 -07005286status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
5287 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07005288{
Eric Laurent1f2f2232014-06-02 12:01:23 -07005289 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07005290 ssize_t index;
5291 if (patchHandle) {
5292 index = mAudioPatches.indexOfKey(*patchHandle);
5293 } else {
Jean-Michel Trivi8c7cf3b2016-02-25 17:08:24 -08005294 index = mAudioPatches.indexOfKey(inputDesc->getPatchHandle());
Eric Laurent6a94d692014-05-20 11:18:06 -07005295 }
5296 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07005297 return INVALID_OPERATION;
5298 }
Eric Laurent6a94d692014-05-20 11:18:06 -07005299 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
5300 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent1c333e22014-05-20 10:48:17 -07005301 ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
Glenn Kastena13cde92016-03-28 15:26:02 -07005302 inputDesc->setPatchHandle(AUDIO_PATCH_HANDLE_NONE);
Eric Laurent6a94d692014-05-20 11:18:06 -07005303 removeAudioPatch(patchDesc->mHandle);
5304 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07005305 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07005306 return status;
5307}
5308
Jean-Michel Trivi56ec4ff2015-01-23 16:45:18 -08005309sp<IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07005310 const String8& address,
François Gaffie53615e22015-03-19 09:24:12 +01005311 uint32_t& samplingRate,
Andy Hungf129b032015-04-07 13:45:50 -07005312 audio_format_t& format,
5313 audio_channel_mask_t& channelMask,
François Gaffie53615e22015-03-19 09:24:12 +01005314 audio_input_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07005315{
5316 // Choose an input profile based on the requested capture parameters: select the first available
5317 // profile supporting all requested parameters.
Andy Hungf129b032015-04-07 13:45:50 -07005318 //
5319 // TODO: perhaps isCompatibleProfile should return a "matching" score so we can return
5320 // the best matching profile, not the first one.
Eric Laurente552edb2014-03-10 17:42:56 -07005321
5322 for (size_t i = 0; i < mHwModules.size(); i++)
5323 {
5324 if (mHwModules[i]->mHandle == 0) {
5325 continue;
5326 }
5327 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
5328 {
Eric Laurent1c333e22014-05-20 10:48:17 -07005329 sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07005330 // profile->log();
Eric Laurent275e8e92014-11-30 15:14:47 -08005331 if (profile->isCompatibleProfile(device, address, samplingRate,
Glenn Kastencbd48022014-07-24 13:46:44 -07005332 &samplingRate /*updatedSamplingRate*/,
Andy Hungf129b032015-04-07 13:45:50 -07005333 format,
5334 &format /*updatedFormat*/,
5335 channelMask,
5336 &channelMask /*updatedChannelMask*/,
5337 (audio_output_flags_t) flags)) {
Eric Laurent275e8e92014-11-30 15:14:47 -08005338
Eric Laurente552edb2014-03-10 17:42:56 -07005339 return profile;
5340 }
5341 }
5342 }
5343 return NULL;
5344}
5345
Eric Laurentc73ca6e2014-12-12 14:34:22 -08005346
5347audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource,
François Gaffie53615e22015-03-19 09:24:12 +01005348 AudioMix **policyMix)
Eric Laurente552edb2014-03-10 17:42:56 -07005349{
François Gaffie036e1e92015-03-19 10:16:24 +01005350 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
5351 audio_devices_t selectedDeviceFromMix =
5352 mPolicyMixes.getDeviceAndMixForInputSource(inputSource, availableDeviceTypes, policyMix);
Eric Laurent275e8e92014-11-30 15:14:47 -08005353
François Gaffie036e1e92015-03-19 10:16:24 +01005354 if (selectedDeviceFromMix != AUDIO_DEVICE_NONE) {
5355 return selectedDeviceFromMix;
Eric Laurent275e8e92014-11-30 15:14:47 -08005356 }
Eric Laurentc73ca6e2014-12-12 14:34:22 -08005357 return getDeviceForInputSource(inputSource);
5358}
5359
5360audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
5361{
Eric Laurentad2e7b92017-09-14 20:06:42 -07005362 // Routing
5363 // Scan the whole RouteMap to see if we have an explicit route:
5364 // if the input source in the RouteMap is the same as the argument above,
5365 // and activity count is non-zero and the device in the route descriptor is available
5366 // then select this device.
Paul McLean466dc8e2015-04-17 13:15:36 -06005367 for (size_t routeIndex = 0; routeIndex < mInputRoutes.size(); routeIndex++) {
5368 sp<SessionRoute> route = mInputRoutes.valueAt(routeIndex);
Eric Laurentad2e7b92017-09-14 20:06:42 -07005369 if ((inputSource == route->mSource) && route->isActive() &&
5370 (mAvailableInputDevices.indexOf(route->mDeviceDescriptor) >= 0)) {
Paul McLean466dc8e2015-04-17 13:15:36 -06005371 return route->mDeviceDescriptor->type();
5372 }
5373 }
5374
5375 return mEngine->getDeviceForInputSource(inputSource);
Eric Laurente552edb2014-03-10 17:42:56 -07005376}
5377
Eric Laurente0720872014-03-11 09:30:41 -07005378float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
François Gaffied1ab2bd2015-12-02 18:20:06 +01005379 int index,
5380 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07005381{
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005382 float volumeDB = mVolumeCurves->volIndexToDb(stream, Volume::getDeviceCategory(device), index);
Jean-Michel Trivi3d8b4a42016-09-14 18:37:46 -07005383
5384 // handle the case of accessibility active while a ringtone is playing: if the ringtone is much
5385 // louder than the accessibility prompt, the prompt cannot be heard, thus masking the touch
5386 // exploration of the dialer UI. In this situation, bring the accessibility volume closer to
5387 // the ringtone volume
5388 if ((stream == AUDIO_STREAM_ACCESSIBILITY)
5389 && (AUDIO_MODE_RINGTONE == mEngine->getPhoneState())
5390 && isStreamActive(AUDIO_STREAM_RING, 0)) {
5391 const float ringVolumeDB = computeVolume(AUDIO_STREAM_RING, index, device);
5392 return ringVolumeDB - 4 > volumeDB ? ringVolumeDB - 4 : volumeDB;
5393 }
5394
Jean-Michel Trivi719a9872017-08-05 13:51:35 -07005395 // in-call: always cap earpiece volume by voice volume + some low headroom
5396 if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) && isInCall()) {
5397 switch (stream) {
5398 case AUDIO_STREAM_SYSTEM:
5399 case AUDIO_STREAM_RING:
5400 case AUDIO_STREAM_MUSIC:
5401 case AUDIO_STREAM_ALARM:
5402 case AUDIO_STREAM_NOTIFICATION:
5403 case AUDIO_STREAM_ENFORCED_AUDIBLE:
5404 case AUDIO_STREAM_DTMF:
5405 case AUDIO_STREAM_ACCESSIBILITY: {
5406 const float maxVoiceVolDb = computeVolume(AUDIO_STREAM_VOICE_CALL, index, device)
5407 + IN_CALL_EARPIECE_HEADROOM_DB;
5408 if (volumeDB > maxVoiceVolDb) {
5409 ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
5410 stream, volumeDB, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
5411 volumeDB = maxVoiceVolDb;
5412 }
5413 } break;
5414 default:
5415 break;
5416 }
5417 }
5418
Eric Laurente552edb2014-03-10 17:42:56 -07005419 // if a headset is connected, apply the following rules to ring tones and notifications
5420 // to avoid sound level bursts in user's ears:
Eric Laurent6af1c1d2016-04-14 11:20:44 -07005421 // - always attenuate notifications volume by 6dB
5422 // - attenuate ring tones volume by 6dB unless music is not playing and
5423 // speaker is part of the select devices
Eric Laurente552edb2014-03-10 17:42:56 -07005424 // - if music is playing, always limit the volume to current music volume,
5425 // with a minimum threshold at -36dB so that notification is always perceived.
Eric Laurent3b73df72014-03-11 09:06:29 -07005426 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07005427 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
5428 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
5429 AUDIO_DEVICE_OUT_WIRED_HEADSET |
Eric Laurent904d6322017-03-17 17:20:47 -07005430 AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
5431 AUDIO_DEVICE_OUT_USB_HEADSET)) &&
Eric Laurente552edb2014-03-10 17:42:56 -07005432 ((stream_strategy == STRATEGY_SONIFICATION)
5433 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
Eric Laurent3b73df72014-03-11 09:06:29 -07005434 || (stream == AUDIO_STREAM_SYSTEM)
Eric Laurente552edb2014-03-10 17:42:56 -07005435 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
François Gaffie2110e042015-03-24 08:41:51 +01005436 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) &&
François Gaffied1ab2bd2015-12-02 18:20:06 +01005437 mVolumeCurves->canBeMuted(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005438 // when the phone is ringing we must consider that music could have been paused just before
5439 // by the music application and behave as if music was active if the last music track was
5440 // just stopped
Eric Laurent3b73df72014-03-11 09:06:29 -07005441 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
Eric Laurente552edb2014-03-10 17:42:56 -07005442 mLimitRingtoneVolume) {
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005443 volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
Eric Laurente552edb2014-03-10 17:42:56 -07005444 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
Eric Laurentffbc80f2015-03-18 18:30:19 -07005445 float musicVolDB = computeVolume(AUDIO_STREAM_MUSIC,
François Gaffied1ab2bd2015-12-02 18:20:06 +01005446 mVolumeCurves->getVolumeIndex(AUDIO_STREAM_MUSIC,
5447 musicDevice),
5448 musicDevice);
Eric Laurentffbc80f2015-03-18 18:30:19 -07005449 float minVolDB = (musicVolDB > SONIFICATION_HEADSET_VOLUME_MIN_DB) ?
5450 musicVolDB : SONIFICATION_HEADSET_VOLUME_MIN_DB;
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005451 if (volumeDB > minVolDB) {
5452 volumeDB = minVolDB;
Eric Laurentffbc80f2015-03-18 18:30:19 -07005453 ALOGV("computeVolume limiting volume to %f musicVol %f", minVolDB, musicVolDB);
Eric Laurente552edb2014-03-10 17:42:56 -07005454 }
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005455 if (device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
5456 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES)) {
5457 // on A2DP, also ensure notification volume is not too low compared to media when
5458 // intended to be played
5459 if ((volumeDB > -96.0f) &&
5460 (musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB > volumeDB)) {
5461 ALOGV("computeVolume increasing volume for stream=%d device=0x%X from %f to %f",
5462 stream, device,
5463 volumeDB, musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB);
5464 volumeDB = musicVolDB - SONIFICATION_A2DP_MAX_MEDIA_DIFF_DB;
5465 }
5466 }
Eric Laurent6af1c1d2016-04-14 11:20:44 -07005467 } else if ((Volume::getDeviceForVolume(device) != AUDIO_DEVICE_OUT_SPEAKER) ||
5468 stream_strategy != STRATEGY_SONIFICATION) {
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005469 volumeDB += SONIFICATION_HEADSET_VOLUME_FACTOR_DB;
Eric Laurente552edb2014-03-10 17:42:56 -07005470 }
5471 }
5472
Jean-Michel Trivi00a20962016-05-25 19:11:01 -07005473 return volumeDB;
Eric Laurente552edb2014-03-10 17:42:56 -07005474}
5475
Eric Laurente0720872014-03-11 09:30:41 -07005476status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07005477 int index,
5478 const sp<AudioOutputDescriptor>& outputDesc,
5479 audio_devices_t device,
5480 int delayMs,
5481 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07005482{
Eric Laurente552edb2014-03-10 17:42:56 -07005483 // do not change actual stream volume if the stream is muted
Eric Laurentc75307b2015-03-17 15:29:32 -07005484 if (outputDesc->mMuteCount[stream] != 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07005485 ALOGVV("checkAndSetVolume() stream %d muted count %d",
Eric Laurentc75307b2015-03-17 15:29:32 -07005486 stream, outputDesc->mMuteCount[stream]);
Eric Laurente552edb2014-03-10 17:42:56 -07005487 return NO_ERROR;
5488 }
François Gaffie2110e042015-03-24 08:41:51 +01005489 audio_policy_forced_cfg_t forceUseForComm =
5490 mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
Eric Laurente552edb2014-03-10 17:42:56 -07005491 // do not change in call volume if bluetooth is connected and vice versa
François Gaffie2110e042015-03-24 08:41:51 +01005492 if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
5493 (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005494 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
François Gaffie2110e042015-03-24 08:41:51 +01005495 stream, forceUseForComm);
Eric Laurente552edb2014-03-10 17:42:56 -07005496 return INVALID_OPERATION;
5497 }
5498
Eric Laurentc75307b2015-03-17 15:29:32 -07005499 if (device == AUDIO_DEVICE_NONE) {
5500 device = outputDesc->device();
5501 }
Eric Laurent275e8e92014-11-30 15:14:47 -08005502
Eric Laurentffbc80f2015-03-18 18:30:19 -07005503 float volumeDb = computeVolume(stream, index, device);
Eric Laurentc75307b2015-03-17 15:29:32 -07005504 if (outputDesc->isFixedVolume(device)) {
Eric Laurentffbc80f2015-03-18 18:30:19 -07005505 volumeDb = 0.0f;
Eric Laurent275e8e92014-11-30 15:14:47 -08005506 }
Eric Laurentc75307b2015-03-17 15:29:32 -07005507
Eric Laurentffbc80f2015-03-18 18:30:19 -07005508 outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
Eric Laurente552edb2014-03-10 17:42:56 -07005509
Eric Laurent3b73df72014-03-11 09:06:29 -07005510 if (stream == AUDIO_STREAM_VOICE_CALL ||
5511 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
Eric Laurente552edb2014-03-10 17:42:56 -07005512 float voiceVolume;
5513 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
Eric Laurent3b73df72014-03-11 09:06:29 -07005514 if (stream == AUDIO_STREAM_VOICE_CALL) {
François Gaffied1ab2bd2015-12-02 18:20:06 +01005515 voiceVolume = (float)index/(float)mVolumeCurves->getVolumeIndexMax(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07005516 } else {
5517 voiceVolume = 1.0;
5518 }
5519
Eric Laurent18fba842016-03-31 14:41:26 -07005520 if (voiceVolume != mLastVoiceVolume) {
Eric Laurente552edb2014-03-10 17:42:56 -07005521 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
5522 mLastVoiceVolume = voiceVolume;
5523 }
5524 }
5525
5526 return NO_ERROR;
5527}
5528
Eric Laurentc75307b2015-03-17 15:29:32 -07005529void AudioPolicyManager::applyStreamVolumes(const sp<AudioOutputDescriptor>& outputDesc,
5530 audio_devices_t device,
5531 int delayMs,
5532 bool force)
Eric Laurente552edb2014-03-10 17:42:56 -07005533{
Eric Laurentc75307b2015-03-17 15:29:32 -07005534 ALOGVV("applyStreamVolumes() for device %08x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07005535
Eric Laurent794fde22016-03-11 09:50:45 -08005536 for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005537 checkAndSetVolume((audio_stream_type_t)stream,
François Gaffied1ab2bd2015-12-02 18:20:06 +01005538 mVolumeCurves->getVolumeIndex((audio_stream_type_t)stream, device),
Eric Laurentc75307b2015-03-17 15:29:32 -07005539 outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07005540 device,
5541 delayMs,
5542 force);
5543 }
5544}
5545
Eric Laurente0720872014-03-11 09:30:41 -07005546void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
Eric Laurentc75307b2015-03-17 15:29:32 -07005547 bool on,
5548 const sp<AudioOutputDescriptor>& outputDesc,
5549 int delayMs,
5550 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07005551{
Eric Laurent72249d52015-06-08 11:12:15 -07005552 ALOGVV("setStrategyMute() strategy %d, mute %d, output ID %d",
5553 strategy, on, outputDesc->getId());
Eric Laurent794fde22016-03-11 09:50:45 -08005554 for (int stream = 0; stream < AUDIO_STREAM_FOR_POLICY_CNT; stream++) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005555 if (getStrategy((audio_stream_type_t)stream) == strategy) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005556 setStreamMute((audio_stream_type_t)stream, on, outputDesc, delayMs, device);
Eric Laurente552edb2014-03-10 17:42:56 -07005557 }
5558 }
5559}
5560
Eric Laurente0720872014-03-11 09:30:41 -07005561void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
Eric Laurentc75307b2015-03-17 15:29:32 -07005562 bool on,
5563 const sp<AudioOutputDescriptor>& outputDesc,
5564 int delayMs,
5565 audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07005566{
Eric Laurente552edb2014-03-10 17:42:56 -07005567 if (device == AUDIO_DEVICE_NONE) {
5568 device = outputDesc->device();
5569 }
5570
Eric Laurentc75307b2015-03-17 15:29:32 -07005571 ALOGVV("setStreamMute() stream %d, mute %d, mMuteCount %d device %04x",
5572 stream, on, outputDesc->mMuteCount[stream], device);
Eric Laurente552edb2014-03-10 17:42:56 -07005573
5574 if (on) {
5575 if (outputDesc->mMuteCount[stream] == 0) {
François Gaffied1ab2bd2015-12-02 18:20:06 +01005576 if (mVolumeCurves->canBeMuted(stream) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07005577 ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
François Gaffie2110e042015-03-24 08:41:51 +01005578 (mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_NONE))) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005579 checkAndSetVolume(stream, 0, outputDesc, device, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07005580 }
5581 }
5582 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
5583 outputDesc->mMuteCount[stream]++;
5584 } else {
5585 if (outputDesc->mMuteCount[stream] == 0) {
5586 ALOGV("setStreamMute() unmuting non muted stream!");
5587 return;
5588 }
5589 if (--outputDesc->mMuteCount[stream] == 0) {
5590 checkAndSetVolume(stream,
François Gaffied1ab2bd2015-12-02 18:20:06 +01005591 mVolumeCurves->getVolumeIndex(stream, device),
Eric Laurentc75307b2015-03-17 15:29:32 -07005592 outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07005593 device,
5594 delayMs);
5595 }
5596 }
5597}
5598
Eric Laurente0720872014-03-11 09:30:41 -07005599void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07005600 bool starting, bool stateChange)
Eric Laurente552edb2014-03-10 17:42:56 -07005601{
Eric Laurent87ffa392015-05-22 10:32:38 -07005602 if(!hasPrimaryOutput()) {
5603 return;
5604 }
5605
Eric Laurente552edb2014-03-10 17:42:56 -07005606 // if the stream pertains to sonification strategy and we are in call we must
5607 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
5608 // in the device used for phone strategy and play the tone if the selected device does not
5609 // interfere with the device used for phone strategy
5610 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
5611 // many times as there are active tracks on the output
Eric Laurent3b73df72014-03-11 09:06:29 -07005612 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07005613 if ((stream_strategy == STRATEGY_SONIFICATION) ||
5614 ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
Eric Laurentc75307b2015-03-17 15:29:32 -07005615 sp<SwAudioOutputDescriptor> outputDesc = mPrimaryOutput;
Eric Laurente552edb2014-03-10 17:42:56 -07005616 ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
5617 stream, starting, outputDesc->mDevice, stateChange);
5618 if (outputDesc->mRefCount[stream]) {
5619 int muteCount = 1;
5620 if (stateChange) {
5621 muteCount = outputDesc->mRefCount[stream];
5622 }
Eric Laurent3b73df72014-03-11 09:06:29 -07005623 if (audio_is_low_visibility(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005624 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
5625 for (int i = 0; i < muteCount; i++) {
5626 setStreamMute(stream, starting, mPrimaryOutput);
5627 }
5628 } else {
5629 ALOGV("handleIncallSonification() high visibility");
5630 if (outputDesc->device() &
5631 getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
5632 ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
5633 for (int i = 0; i < muteCount; i++) {
5634 setStreamMute(stream, starting, mPrimaryOutput);
5635 }
5636 }
5637 if (starting) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005638 mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
5639 AUDIO_STREAM_VOICE_CALL);
Eric Laurente552edb2014-03-10 17:42:56 -07005640 } else {
5641 mpClientInterface->stopTone();
5642 }
5643 }
5644 }
5645 }
5646}
5647
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07005648audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
5649{
5650 // flags to stream type mapping
5651 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
5652 return AUDIO_STREAM_ENFORCED_AUDIBLE;
5653 }
5654 if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
5655 return AUDIO_STREAM_BLUETOOTH_SCO;
5656 }
Jean-Michel Trivi79ad4382015-01-29 10:49:39 -08005657 if ((attr->flags & AUDIO_FLAG_BEACON) == AUDIO_FLAG_BEACON) {
5658 return AUDIO_STREAM_TTS;
5659 }
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07005660
5661 // usage to stream type mapping
5662 switch (attr->usage) {
5663 case AUDIO_USAGE_MEDIA:
5664 case AUDIO_USAGE_GAME:
Jean-Michel Trivi36867762016-12-29 12:03:28 -08005665 case AUDIO_USAGE_ASSISTANT:
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07005666 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
5667 return AUDIO_STREAM_MUSIC;
Eric Laurent223fd5c2014-11-11 13:43:36 -08005668 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5669 return AUDIO_STREAM_ACCESSIBILITY;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07005670 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
5671 return AUDIO_STREAM_SYSTEM;
5672 case AUDIO_USAGE_VOICE_COMMUNICATION:
5673 return AUDIO_STREAM_VOICE_CALL;
5674
5675 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
5676 return AUDIO_STREAM_DTMF;
5677
5678 case AUDIO_USAGE_ALARM:
5679 return AUDIO_STREAM_ALARM;
5680 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
5681 return AUDIO_STREAM_RING;
5682
5683 case AUDIO_USAGE_NOTIFICATION:
5684 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
5685 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
5686 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
5687 case AUDIO_USAGE_NOTIFICATION_EVENT:
5688 return AUDIO_STREAM_NOTIFICATION;
5689
5690 case AUDIO_USAGE_UNKNOWN:
5691 default:
5692 return AUDIO_STREAM_MUSIC;
5693 }
5694}
Eric Laurente83b55d2014-11-14 10:06:21 -08005695
François Gaffie53615e22015-03-19 09:24:12 +01005696bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa)
5697{
Eric Laurente83b55d2014-11-14 10:06:21 -08005698 // has flags that map to a strategy?
5699 if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) {
5700 return true;
5701 }
5702
5703 // has known usage?
5704 switch (paa->usage) {
5705 case AUDIO_USAGE_UNKNOWN:
5706 case AUDIO_USAGE_MEDIA:
5707 case AUDIO_USAGE_VOICE_COMMUNICATION:
5708 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
5709 case AUDIO_USAGE_ALARM:
5710 case AUDIO_USAGE_NOTIFICATION:
5711 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
5712 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
5713 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
5714 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
5715 case AUDIO_USAGE_NOTIFICATION_EVENT:
5716 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
5717 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
5718 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
5719 case AUDIO_USAGE_GAME:
Eric Laurent275e8e92014-11-30 15:14:47 -08005720 case AUDIO_USAGE_VIRTUAL_SOURCE:
Jean-Michel Trivi36867762016-12-29 12:03:28 -08005721 case AUDIO_USAGE_ASSISTANT:
Eric Laurente83b55d2014-11-14 10:06:21 -08005722 break;
5723 default:
5724 return false;
5725 }
5726 return true;
5727}
5728
Chih-Hung Hsiehe964d4e2016-08-09 14:31:32 -07005729bool AudioPolicyManager::isStrategyActive(const sp<AudioOutputDescriptor>& outputDesc,
François Gaffiead3183e2015-03-18 16:55:35 +01005730 routing_strategy strategy, uint32_t inPastMs,
5731 nsecs_t sysTime) const
5732{
5733 if ((sysTime == 0) && (inPastMs != 0)) {
5734 sysTime = systemTime();
5735 }
Eric Laurent794fde22016-03-11 09:50:45 -08005736 for (int i = 0; i < (int)AUDIO_STREAM_FOR_POLICY_CNT; i++) {
François Gaffiead3183e2015-03-18 16:55:35 +01005737 if (((getStrategy((audio_stream_type_t)i) == strategy) ||
5738 (NUM_STRATEGIES == strategy)) &&
5739 outputDesc->isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
5740 return true;
5741 }
5742 }
5743 return false;
5744}
5745
François Gaffie2110e042015-03-24 08:41:51 +01005746audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
5747{
5748 return mEngine->getForceUse(usage);
5749}
5750
5751bool AudioPolicyManager::isInCall()
5752{
5753 return isStateInCall(mEngine->getPhoneState());
5754}
5755
5756bool AudioPolicyManager::isStateInCall(int state)
5757{
5758 return is_state_in_call(state);
5759}
5760
Eric Laurentd60560a2015-04-10 11:31:20 -07005761void AudioPolicyManager::cleanUpForDevice(const sp<DeviceDescriptor>& deviceDesc)
5762{
5763 for (ssize_t i = (ssize_t)mAudioSources.size() - 1; i >= 0; i--) {
5764 sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueAt(i);
5765 if (sourceDesc->mDevice->equals(deviceDesc)) {
5766 ALOGV("%s releasing audio source %d", __FUNCTION__, sourceDesc->getHandle());
5767 stopAudioSource(sourceDesc->getHandle());
5768 }
5769 }
5770
5771 for (ssize_t i = (ssize_t)mAudioPatches.size() - 1; i >= 0; i--) {
5772 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
5773 bool release = false;
5774 for (size_t j = 0; j < patchDesc->mPatch.num_sources && !release; j++) {
5775 const struct audio_port_config *source = &patchDesc->mPatch.sources[j];
5776 if (source->type == AUDIO_PORT_TYPE_DEVICE &&
5777 source->ext.device.type == deviceDesc->type()) {
5778 release = true;
5779 }
5780 }
5781 for (size_t j = 0; j < patchDesc->mPatch.num_sinks && !release; j++) {
5782 const struct audio_port_config *sink = &patchDesc->mPatch.sinks[j];
5783 if (sink->type == AUDIO_PORT_TYPE_DEVICE &&
5784 sink->ext.device.type == deviceDesc->type()) {
5785 release = true;
5786 }
5787 }
5788 if (release) {
5789 ALOGV("%s releasing patch %u", __FUNCTION__, patchDesc->mHandle);
5790 releaseAudioPatch(patchDesc->mHandle, patchDesc->mUid);
5791 }
5792 }
5793}
5794
Phil Burk09bc4612016-02-24 15:58:15 -08005795// Modify the list of surround sound formats supported.
Phil Burk0709b0a2016-03-31 12:54:57 -07005796void AudioPolicyManager::filterSurroundFormats(FormatVector *formatsPtr) {
5797 FormatVector &formats = *formatsPtr;
Phil Burk07ac1142016-03-25 13:39:29 -07005798 // TODO Set this based on Config properties.
5799 const bool alwaysForceAC3 = true;
Phil Burk09bc4612016-02-24 15:58:15 -08005800
5801 audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
5802 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
Phil Burk0709b0a2016-03-31 12:54:57 -07005803 ALOGD("%s: forced use = %d", __FUNCTION__, forceUse);
Phil Burk09bc4612016-02-24 15:58:15 -08005804
5805 // Analyze original support for various formats.
Phil Burk07ac1142016-03-25 13:39:29 -07005806 bool supportsAC3 = false;
5807 bool supportsOtherSurround = false;
Phil Burk09bc4612016-02-24 15:58:15 -08005808 bool supportsIEC61937 = false;
5809 for (size_t formatIndex = 0; formatIndex < formats.size(); formatIndex++) {
5810 audio_format_t format = formats[formatIndex];
Phil Burk09bc4612016-02-24 15:58:15 -08005811 switch (format) {
5812 case AUDIO_FORMAT_AC3:
Phil Burk07ac1142016-03-25 13:39:29 -07005813 supportsAC3 = true;
5814 break;
Phil Burk09bc4612016-02-24 15:58:15 -08005815 case AUDIO_FORMAT_E_AC3:
5816 case AUDIO_FORMAT_DTS:
5817 case AUDIO_FORMAT_DTS_HD:
Phil Burk07ac1142016-03-25 13:39:29 -07005818 supportsOtherSurround = true;
Phil Burk09bc4612016-02-24 15:58:15 -08005819 break;
5820 case AUDIO_FORMAT_IEC61937:
5821 supportsIEC61937 = true;
5822 break;
5823 default:
5824 break;
5825 }
5826 }
Phil Burk09bc4612016-02-24 15:58:15 -08005827
5828 // Modify formats based on surround preferences.
5829 // If NEVER, remove support for surround formats.
Phil Burk07ac1142016-03-25 13:39:29 -07005830 if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
5831 if (supportsAC3 || supportsOtherSurround || supportsIEC61937) {
5832 // Remove surround sound related formats.
5833 for (size_t formatIndex = 0; formatIndex < formats.size(); ) {
5834 audio_format_t format = formats[formatIndex];
5835 switch(format) {
5836 case AUDIO_FORMAT_AC3:
5837 case AUDIO_FORMAT_E_AC3:
5838 case AUDIO_FORMAT_DTS:
5839 case AUDIO_FORMAT_DTS_HD:
5840 case AUDIO_FORMAT_IEC61937:
Phil Burk07ac1142016-03-25 13:39:29 -07005841 formats.removeAt(formatIndex);
5842 break;
5843 default:
5844 formatIndex++; // keep it
5845 break;
5846 }
Phil Burk09bc4612016-02-24 15:58:15 -08005847 }
Phil Burk07ac1142016-03-25 13:39:29 -07005848 supportsAC3 = false;
5849 supportsOtherSurround = false;
5850 supportsIEC61937 = false;
Phil Burk09bc4612016-02-24 15:58:15 -08005851 }
Phil Burk07ac1142016-03-25 13:39:29 -07005852 } else { // AUTO or ALWAYS
5853 // Most TVs support AC3 even if they do not report it in the EDID.
5854 if ((alwaysForceAC3 || (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS))
5855 && !supportsAC3) {
5856 formats.add(AUDIO_FORMAT_AC3);
5857 supportsAC3 = true;
5858 }
5859
5860 // If ALWAYS, add support for raw surround formats if all are missing.
5861 // This assumes that if any of these formats are reported by the HAL
5862 // then the report is valid and should not be modified.
5863 if ((forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS)
5864 && !supportsOtherSurround) {
5865 formats.add(AUDIO_FORMAT_E_AC3);
5866 formats.add(AUDIO_FORMAT_DTS);
5867 formats.add(AUDIO_FORMAT_DTS_HD);
5868 supportsOtherSurround = true;
5869 }
5870
5871 // Add support for IEC61937 if any raw surround supported.
5872 // The HAL could do this but add it here, just in case.
5873 if ((supportsAC3 || supportsOtherSurround) && !supportsIEC61937) {
5874 formats.add(AUDIO_FORMAT_IEC61937);
5875 supportsIEC61937 = true;
5876 }
Phil Burk09bc4612016-02-24 15:58:15 -08005877 }
Phil Burk0709b0a2016-03-31 12:54:57 -07005878}
5879
5880// Modify the list of channel masks supported.
5881void AudioPolicyManager::filterSurroundChannelMasks(ChannelsVector *channelMasksPtr) {
5882 ChannelsVector &channelMasks = *channelMasksPtr;
5883 audio_policy_forced_cfg_t forceUse = mEngine->getForceUse(
5884 AUDIO_POLICY_FORCE_FOR_ENCODED_SURROUND);
5885
5886 // If NEVER, then remove support for channelMasks > stereo.
5887 if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_NEVER) {
5888 for (size_t maskIndex = 0; maskIndex < channelMasks.size(); ) {
5889 audio_channel_mask_t channelMask = channelMasks[maskIndex];
5890 if (channelMask & ~AUDIO_CHANNEL_OUT_STEREO) {
5891 ALOGI("%s: force NEVER, so remove channelMask 0x%08x", __FUNCTION__, channelMask);
5892 channelMasks.removeAt(maskIndex);
5893 } else {
5894 maskIndex++;
5895 }
5896 }
5897 // If ALWAYS, then make sure we at least support 5.1
5898 } else if (forceUse == AUDIO_POLICY_FORCE_ENCODED_SURROUND_ALWAYS) {
5899 bool supports5dot1 = false;
5900 // Are there any channel masks that can be considered "surround"?
5901 for (size_t maskIndex = 0; maskIndex < channelMasks.size(); maskIndex++) {
5902 audio_channel_mask_t channelMask = channelMasks[maskIndex];
5903 if ((channelMask & AUDIO_CHANNEL_OUT_5POINT1) == AUDIO_CHANNEL_OUT_5POINT1) {
5904 supports5dot1 = true;
5905 break;
5906 }
5907 }
5908 // If not then add 5.1 support.
5909 if (!supports5dot1) {
5910 channelMasks.add(AUDIO_CHANNEL_OUT_5POINT1);
5911 ALOGI("%s: force ALWAYS, so adding channelMask for 5.1 surround", __FUNCTION__);
5912 }
Phil Burk09bc4612016-02-24 15:58:15 -08005913 }
5914}
5915
Phil Burk00eeb322016-03-31 12:41:00 -07005916void AudioPolicyManager::updateAudioProfiles(audio_devices_t device,
5917 audio_io_handle_t ioHandle,
François Gaffie112b0af2015-11-19 16:13:25 +01005918 AudioProfileVector &profiles)
5919{
5920 String8 reply;
Phil Burk0709b0a2016-03-31 12:54:57 -07005921
François Gaffie112b0af2015-11-19 16:13:25 +01005922 // Format MUST be checked first to update the list of AudioProfile
5923 if (profiles.hasDynamicFormat()) {
Mikhail Naganov388360c2016-10-17 17:09:41 -07005924 reply = mpClientInterface->getParameters(
5925 ioHandle, String8(AudioParameter::keyStreamSupportedFormats));
Phil Burk0709b0a2016-03-31 12:54:57 -07005926 ALOGV("%s: supported formats %s", __FUNCTION__, reply.string());
Eric Laurent62e4bc52016-02-02 18:37:28 -08005927 AudioParameter repliedParameters(reply);
5928 if (repliedParameters.get(
Mikhail Naganov388360c2016-10-17 17:09:41 -07005929 String8(AudioParameter::keyStreamSupportedFormats), reply) != NO_ERROR) {
François Gaffie112b0af2015-11-19 16:13:25 +01005930 ALOGE("%s: failed to retrieve format, bailing out", __FUNCTION__);
5931 return;
5932 }
Phil Burk09bc4612016-02-24 15:58:15 -08005933 FormatVector formats = formatsFromString(reply.string());
Phil Burk00eeb322016-03-31 12:41:00 -07005934 if (device == AUDIO_DEVICE_OUT_HDMI) {
Phil Burk0709b0a2016-03-31 12:54:57 -07005935 filterSurroundFormats(&formats);
Phil Burk00eeb322016-03-31 12:41:00 -07005936 }
Phil Burk09bc4612016-02-24 15:58:15 -08005937 profiles.setFormats(formats);
François Gaffie112b0af2015-11-19 16:13:25 +01005938 }
5939 const FormatVector &supportedFormats = profiles.getSupportedFormats();
5940
Eric Laurent20eb3a42016-01-26 18:39:17 -08005941 for (size_t formatIndex = 0; formatIndex < supportedFormats.size(); formatIndex++) {
François Gaffie112b0af2015-11-19 16:13:25 +01005942 audio_format_t format = supportedFormats[formatIndex];
Eric Laurent20eb3a42016-01-26 18:39:17 -08005943 ChannelsVector channelMasks;
5944 SampleRateVector samplingRates;
François Gaffie112b0af2015-11-19 16:13:25 +01005945 AudioParameter requestedParameters;
Mikhail Naganov388360c2016-10-17 17:09:41 -07005946 requestedParameters.addInt(String8(AudioParameter::keyFormat), format);
François Gaffie112b0af2015-11-19 16:13:25 +01005947
5948 if (profiles.hasDynamicRateFor(format)) {
Mikhail Naganov388360c2016-10-17 17:09:41 -07005949 reply = mpClientInterface->getParameters(
5950 ioHandle,
5951 requestedParameters.toString() + ";" +
5952 AudioParameter::keyStreamSupportedSamplingRates);
François Gaffie112b0af2015-11-19 16:13:25 +01005953 ALOGV("%s: supported sampling rates %s", __FUNCTION__, reply.string());
Eric Laurent62e4bc52016-02-02 18:37:28 -08005954 AudioParameter repliedParameters(reply);
5955 if (repliedParameters.get(
Mikhail Naganov388360c2016-10-17 17:09:41 -07005956 String8(AudioParameter::keyStreamSupportedSamplingRates), reply) == NO_ERROR) {
Eric Laurent62e4bc52016-02-02 18:37:28 -08005957 samplingRates = samplingRatesFromString(reply.string());
François Gaffie112b0af2015-11-19 16:13:25 +01005958 }
5959 }
5960 if (profiles.hasDynamicChannelsFor(format)) {
5961 reply = mpClientInterface->getParameters(ioHandle,
5962 requestedParameters.toString() + ";" +
Mikhail Naganov388360c2016-10-17 17:09:41 -07005963 AudioParameter::keyStreamSupportedChannels);
François Gaffie112b0af2015-11-19 16:13:25 +01005964 ALOGV("%s: supported channel masks %s", __FUNCTION__, reply.string());
Eric Laurent62e4bc52016-02-02 18:37:28 -08005965 AudioParameter repliedParameters(reply);
5966 if (repliedParameters.get(
Mikhail Naganov388360c2016-10-17 17:09:41 -07005967 String8(AudioParameter::keyStreamSupportedChannels), reply) == NO_ERROR) {
Eric Laurent62e4bc52016-02-02 18:37:28 -08005968 channelMasks = channelMasksFromString(reply.string());
Phil Burk0709b0a2016-03-31 12:54:57 -07005969 if (device == AUDIO_DEVICE_OUT_HDMI) {
5970 filterSurroundChannelMasks(&channelMasks);
5971 }
François Gaffie112b0af2015-11-19 16:13:25 +01005972 }
5973 }
Eric Laurent20eb3a42016-01-26 18:39:17 -08005974 profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
François Gaffie112b0af2015-11-19 16:13:25 +01005975 }
5976}
Eric Laurentd60560a2015-04-10 11:31:20 -07005977
Eric Laurente552edb2014-03-10 17:42:56 -07005978}; // namespace android