blob: 41d726c65348b750162a594c9dffbf7773050715 [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
Eric Laurente0720872014-03-11 09:30:41 -070017#define LOG_TAG "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
27// A device mask for all audio input devices that are considered "virtual" when evaluating
28// active inputs in getActiveInput()
29#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL AUDIO_DEVICE_IN_REMOTE_SUBMIX
30// A device mask for all audio output devices that are considered "remote" when evaluating
31// active output devices in isStreamActiveRemotely()
32#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -070033// A device mask for all audio input and output devices where matching inputs/outputs on device
34// type alone is not enough: the address must match too
35#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
36 AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
Eric Laurente552edb2014-03-10 17:42:56 -070037
Eric Laurentd4692962014-05-05 18:13:44 -070038#include <inttypes.h>
Eric Laurente552edb2014-03-10 17:42:56 -070039#include <math.h>
Eric Laurentd4692962014-05-05 18:13:44 -070040
Eric Laurente552edb2014-03-10 17:42:56 -070041#include <cutils/properties.h>
Eric Laurentd4692962014-05-05 18:13:44 -070042#include <utils/Log.h>
43#include <hardware/audio.h>
44#include <hardware/audio_effect.h>
Eric Laurent3b73df72014-03-11 09:06:29 -070045#include <media/AudioParameter.h>
Eric Laurentdf3dc7e2014-07-27 18:39:40 -070046#include <soundtrigger/SoundTrigger.h>
Eric Laurentd4692962014-05-05 18:13:44 -070047#include "AudioPolicyManager.h"
Eric Laurent1afeecb2014-05-14 08:52:28 -070048#include "audio_policy_conf.h"
Eric Laurente552edb2014-03-10 17:42:56 -070049
Eric Laurent3b73df72014-03-11 09:06:29 -070050namespace android {
Eric Laurente552edb2014-03-10 17:42:56 -070051
52// ----------------------------------------------------------------------------
Eric Laurent3a4311c2014-03-17 12:00:47 -070053// Definitions for audio_policy.conf file parsing
54// ----------------------------------------------------------------------------
55
56struct StringToEnum {
57 const char *name;
58 uint32_t value;
59};
60
61#define STRING_TO_ENUM(string) { #string, string }
62#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
63
64const StringToEnum sDeviceNameToEnumTable[] = {
65 STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
66 STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
67 STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
68 STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
69 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
70 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
71 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
72 STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
73 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
74 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
75 STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
76 STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
77 STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
Eric Laurent1b776232014-05-19 17:26:41 -070078 STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI),
Eric Laurent3a4311c2014-03-17 12:00:47 -070079 STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
80 STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
81 STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
82 STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
83 STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
84 STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
Eric Laurent1b776232014-05-19 17:26:41 -070085 STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
86 STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE),
87 STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
88 STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
89 STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
Eric Laurente1d37b72014-07-29 10:26:26 -070090 STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
Eric Laurenta57ab8d2014-07-30 10:01:42 -050091 STRING_TO_ENUM(AUDIO_DEVICE_IN_AMBIENT),
Eric Laurent3a4311c2014-03-17 12:00:47 -070092 STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
93 STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
94 STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
95 STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
96 STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
Eric Laurent1b776232014-05-19 17:26:41 -070097 STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI),
Eric Laurent1b776232014-05-19 17:26:41 -070098 STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
Eric Laurentc2730ba2014-07-20 15:47:07 -070099 STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700100 STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
101 STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
102 STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
103 STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
104 STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
Eric Laurentd4692962014-05-05 18:13:44 -0700105 STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
Eric Laurent1b776232014-05-19 17:26:41 -0700106 STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
107 STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
108 STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
109 STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
Mike Lockwood41b0e242014-05-13 15:23:35 -0700110 STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
Terry Heo7999a222014-06-27 15:23:36 +0900111 STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700112};
113
114const StringToEnum sFlagNameToEnumTable[] = {
115 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
116 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
117 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
118 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
119 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
120 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
Eric Laurent93c3d412014-08-01 14:48:35 -0700121 STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700122};
123
124const StringToEnum sFormatNameToEnumTable[] = {
125 STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
126 STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
127 STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
128 STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
129 STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
130 STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
131 STRING_TO_ENUM(AUDIO_FORMAT_MP3),
132 STRING_TO_ENUM(AUDIO_FORMAT_AAC),
aarti jadhav-gaikwad2829edc2014-06-18 15:25:26 +0530133 STRING_TO_ENUM(AUDIO_FORMAT_AAC_MAIN),
134 STRING_TO_ENUM(AUDIO_FORMAT_AAC_LC),
135 STRING_TO_ENUM(AUDIO_FORMAT_AAC_SSR),
136 STRING_TO_ENUM(AUDIO_FORMAT_AAC_LTP),
137 STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V1),
138 STRING_TO_ENUM(AUDIO_FORMAT_AAC_SCALABLE),
139 STRING_TO_ENUM(AUDIO_FORMAT_AAC_ERLC),
140 STRING_TO_ENUM(AUDIO_FORMAT_AAC_LD),
141 STRING_TO_ENUM(AUDIO_FORMAT_AAC_HE_V2),
142 STRING_TO_ENUM(AUDIO_FORMAT_AAC_ELD),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700143 STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
Eric Laurentab5cdba2014-06-09 17:22:27 -0700144 STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V1),
145 STRING_TO_ENUM(AUDIO_FORMAT_HE_AAC_V2),
146 STRING_TO_ENUM(AUDIO_FORMAT_OPUS),
147 STRING_TO_ENUM(AUDIO_FORMAT_AC3),
148 STRING_TO_ENUM(AUDIO_FORMAT_E_AC3),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700149};
150
151const StringToEnum sOutChannelsNameToEnumTable[] = {
152 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
153 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
Andy Hung3a0fe122014-07-29 17:56:46 -0700154 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_QUAD),
Eric Laurent3a4311c2014-03-17 12:00:47 -0700155 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
156 STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
157};
158
159const StringToEnum sInChannelsNameToEnumTable[] = {
160 STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
161 STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
162 STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
163};
164
Eric Laurent1afeecb2014-05-14 08:52:28 -0700165const StringToEnum sGainModeNameToEnumTable[] = {
166 STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT),
167 STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS),
168 STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP),
169};
170
Eric Laurent3a4311c2014-03-17 12:00:47 -0700171
172uint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table,
173 size_t size,
174 const char *name)
175{
176 for (size_t i = 0; i < size; i++) {
177 if (strcmp(table[i].name, name) == 0) {
178 ALOGV("stringToEnum() found %s", table[i].name);
179 return table[i].value;
180 }
181 }
182 return 0;
183}
184
185const char *AudioPolicyManager::enumToString(const struct StringToEnum *table,
186 size_t size,
187 uint32_t value)
188{
189 for (size_t i = 0; i < size; i++) {
190 if (table[i].value == value) {
191 return table[i].name;
192 }
193 }
194 return "";
195}
196
197bool AudioPolicyManager::stringToBool(const char *value)
198{
199 return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
200}
201
202
203// ----------------------------------------------------------------------------
Eric Laurente552edb2014-03-10 17:42:56 -0700204// AudioPolicyInterface implementation
205// ----------------------------------------------------------------------------
206
207
Eric Laurente0720872014-03-11 09:30:41 -0700208status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
Eric Laurent3b73df72014-03-11 09:06:29 -0700209 audio_policy_dev_state_t state,
Eric Laurente552edb2014-03-10 17:42:56 -0700210 const char *device_address)
211{
Eric Laurent22226012014-08-01 17:00:54 -0700212 String8 address = (device_address == NULL) ? String8("") : String8(device_address);
Eric Laurente552edb2014-03-10 17:42:56 -0700213
Eric Laurent22226012014-08-01 17:00:54 -0700214 ALOGV("setDeviceConnectionState() device: %x, state %d, address %s",
215 device, state, address.string());
Eric Laurente552edb2014-03-10 17:42:56 -0700216
217 // connect/disconnect only 1 device at a time
218 if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
219
Eric Laurente552edb2014-03-10 17:42:56 -0700220 // handle output devices
221 if (audio_is_output_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700222 SortedVector <audio_io_handle_t> outputs;
223
Eric Laurent1afeecb2014-05-14 08:52:28 -0700224 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
225 devDesc->mAddress = address;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700226 ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
227
Eric Laurente552edb2014-03-10 17:42:56 -0700228 // save a copy of the opened output descriptors before any output is opened or closed
229 // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
230 mPreviousOutputs = mOutputs;
Eric Laurente552edb2014-03-10 17:42:56 -0700231 switch (state)
232 {
233 // handle output device connection
Eric Laurent3b73df72014-03-11 09:06:29 -0700234 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
Eric Laurent3a4311c2014-03-17 12:00:47 -0700235 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700236 ALOGW("setDeviceConnectionState() device already connected: %x", device);
237 return INVALID_OPERATION;
238 }
239 ALOGV("setDeviceConnectionState() connecting device %x", device);
240
Eric Laurente552edb2014-03-10 17:42:56 -0700241 // register new device as available
Eric Laurent3a4311c2014-03-17 12:00:47 -0700242 index = mAvailableOutputDevices.add(devDesc);
243 if (index >= 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700244 sp<HwModule> module = getModuleForDevice(device);
Eric Laurentcf817a22014-08-04 20:36:31 -0700245 if (module == 0) {
246 ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
247 device);
248 mAvailableOutputDevices.remove(devDesc);
249 return INVALID_OPERATION;
250 }
251 mAvailableOutputDevices[index]->mId = nextUniqueId();
Eric Laurent6a94d692014-05-20 11:18:06 -0700252 mAvailableOutputDevices[index]->mModule = module;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700253 } else {
254 return NO_MEMORY;
Eric Laurente552edb2014-03-10 17:42:56 -0700255 }
256
Jean-Michel Trivif17026d2014-08-10 14:30:48 -0700257 if (checkOutputsForDevice(devDesc, state, outputs, address) != NO_ERROR) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -0700258 mAvailableOutputDevices.remove(devDesc);
259 return INVALID_OPERATION;
260 }
261 // outputs should never be empty here
262 ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
263 "checkOutputsForDevice() returned no outputs but status OK");
264 ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
265 outputs.size());
Eric Laurente552edb2014-03-10 17:42:56 -0700266 break;
267 // handle output device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700268 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700269 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700270 ALOGW("setDeviceConnectionState() device not connected: %x", device);
271 return INVALID_OPERATION;
272 }
273
Paul McLean5c477aa2014-08-20 16:47:57 -0700274 ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
275
276 // Set Disconnect to HALs
277 AudioParameter param = AudioParameter(address);
278 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
279 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
280
Eric Laurente552edb2014-03-10 17:42:56 -0700281 // remove device from available output devices
Eric Laurent3a4311c2014-03-17 12:00:47 -0700282 mAvailableOutputDevices.remove(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700283
Jean-Michel Trivif17026d2014-08-10 14:30:48 -0700284 checkOutputsForDevice(devDesc, state, outputs, address);
Eric Laurente552edb2014-03-10 17:42:56 -0700285 } break;
286
287 default:
288 ALOGE("setDeviceConnectionState() invalid state: %x", state);
289 return BAD_VALUE;
290 }
291
Eric Laurent3a4311c2014-03-17 12:00:47 -0700292 // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
293 // output is suspended before any tracks are moved to it
Eric Laurente552edb2014-03-10 17:42:56 -0700294 checkA2dpSuspend();
295 checkOutputForAllStrategies();
296 // outputs must be closed after checkOutputForAllStrategies() is executed
297 if (!outputs.isEmpty()) {
298 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700299 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -0700300 // close unused outputs after device disconnection or direct outputs that have been
301 // opened by checkOutputsForDevice() to query dynamic parameters
Eric Laurent3b73df72014-03-11 09:06:29 -0700302 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
Eric Laurente552edb2014-03-10 17:42:56 -0700303 (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
304 (desc->mDirectOpenCount == 0))) {
305 closeOutput(outputs[i]);
306 }
307 }
Eric Laurent3a4311c2014-03-17 12:00:47 -0700308 // check again after closing A2DP output to reset mA2dpSuspended if needed
309 checkA2dpSuspend();
Eric Laurente552edb2014-03-10 17:42:56 -0700310 }
311
312 updateDevicesAndOutputs();
Eric Laurentc2730ba2014-07-20 15:47:07 -0700313 if (mPhoneState == AUDIO_MODE_IN_CALL) {
314 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
315 updateCallRouting(newDevice);
316 }
Eric Laurente552edb2014-03-10 17:42:56 -0700317 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurentc2730ba2014-07-20 15:47:07 -0700318 audio_io_handle_t output = mOutputs.keyAt(i);
319 if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
320 audio_devices_t newDevice = getNewOutputDevice(mOutputs.keyAt(i),
321 true /*fromCache*/);
322 // do not force device change on duplicated output because if device is 0, it will
323 // also force a device 0 for the two outputs it is duplicated to which may override
324 // a valid device selection on those outputs.
325 bool force = !mOutputs.valueAt(i)->isDuplicated()
326 && (!deviceDistinguishesOnAddress(device)
327 // always force when disconnecting (a non-duplicated device)
328 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
329 setOutputDevice(output, newDevice, force, 0);
330 }
Eric Laurente552edb2014-03-10 17:42:56 -0700331 }
332
Eric Laurent72aa32f2014-05-30 18:51:48 -0700333 mpClientInterface->onAudioPortListUpdate();
Eric Laurentb71e58b2014-05-29 16:08:11 -0700334 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700335 } // end if is output device
336
Eric Laurente552edb2014-03-10 17:42:56 -0700337 // handle input devices
338 if (audio_is_input_device(device)) {
Eric Laurentd4692962014-05-05 18:13:44 -0700339 SortedVector <audio_io_handle_t> inputs;
340
Eric Laurent1afeecb2014-05-14 08:52:28 -0700341 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
342 devDesc->mAddress = address;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700343 ssize_t index = mAvailableInputDevices.indexOf(devDesc);
Eric Laurente552edb2014-03-10 17:42:56 -0700344 switch (state)
345 {
346 // handle input device connection
Eric Laurent3b73df72014-03-11 09:06:29 -0700347 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700348 if (index >= 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700349 ALOGW("setDeviceConnectionState() device already connected: %d", device);
350 return INVALID_OPERATION;
351 }
Eric Laurent1f2f2232014-06-02 12:01:23 -0700352 sp<HwModule> module = getModuleForDevice(device);
Eric Laurent6a94d692014-05-20 11:18:06 -0700353 if (module == NULL) {
354 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
355 device);
356 return INVALID_OPERATION;
357 }
Eric Laurentd4692962014-05-05 18:13:44 -0700358 if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) {
359 return INVALID_OPERATION;
360 }
361
Eric Laurent3a4311c2014-03-17 12:00:47 -0700362 index = mAvailableInputDevices.add(devDesc);
363 if (index >= 0) {
364 mAvailableInputDevices[index]->mId = nextUniqueId();
Eric Laurent6a94d692014-05-20 11:18:06 -0700365 mAvailableInputDevices[index]->mModule = module;
Eric Laurent3a4311c2014-03-17 12:00:47 -0700366 } else {
367 return NO_MEMORY;
368 }
Eric Laurentd4692962014-05-05 18:13:44 -0700369 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700370
371 // handle input device disconnection
Eric Laurent3b73df72014-03-11 09:06:29 -0700372 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700373 if (index < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -0700374 ALOGW("setDeviceConnectionState() device not connected: %d", device);
375 return INVALID_OPERATION;
376 }
Paul McLean5c477aa2014-08-20 16:47:57 -0700377
378 ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
379
380 // Set Disconnect to HALs
381 AudioParameter param = AudioParameter(address);
382 param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
383 mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
384
Eric Laurentd4692962014-05-05 18:13:44 -0700385 checkInputsForDevice(device, state, inputs, address);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700386 mAvailableInputDevices.remove(devDesc);
Paul McLean5c477aa2014-08-20 16:47:57 -0700387
Eric Laurentd4692962014-05-05 18:13:44 -0700388 } break;
Eric Laurente552edb2014-03-10 17:42:56 -0700389
390 default:
391 ALOGE("setDeviceConnectionState() invalid state: %x", state);
392 return BAD_VALUE;
393 }
394
Eric Laurentd4692962014-05-05 18:13:44 -0700395 closeAllInputs();
Eric Laurente552edb2014-03-10 17:42:56 -0700396
Eric Laurentc2730ba2014-07-20 15:47:07 -0700397 if (mPhoneState == AUDIO_MODE_IN_CALL) {
398 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
399 updateCallRouting(newDevice);
400 }
401
Eric Laurentb52c1522014-05-20 11:27:36 -0700402 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -0700403 return NO_ERROR;
Eric Laurentd4692962014-05-05 18:13:44 -0700404 } // end if is input device
Eric Laurente552edb2014-03-10 17:42:56 -0700405
406 ALOGW("setDeviceConnectionState() invalid device: %x", device);
407 return BAD_VALUE;
408}
409
Eric Laurente0720872014-03-11 09:30:41 -0700410audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
Eric Laurente552edb2014-03-10 17:42:56 -0700411 const char *device_address)
412{
Eric Laurent3b73df72014-03-11 09:06:29 -0700413 audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurent1afeecb2014-05-14 08:52:28 -0700414 sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
Eric Laurent22226012014-08-01 17:00:54 -0700415 devDesc->mAddress = (device_address == NULL) ? String8("") : String8(device_address);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700416 ssize_t index;
417 DeviceVector *deviceVector;
418
Eric Laurente552edb2014-03-10 17:42:56 -0700419 if (audio_is_output_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700420 deviceVector = &mAvailableOutputDevices;
Eric Laurente552edb2014-03-10 17:42:56 -0700421 } else if (audio_is_input_device(device)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -0700422 deviceVector = &mAvailableInputDevices;
423 } else {
424 ALOGW("getDeviceConnectionState() invalid device type %08x", device);
425 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
Eric Laurente552edb2014-03-10 17:42:56 -0700426 }
427
Eric Laurent3a4311c2014-03-17 12:00:47 -0700428 index = deviceVector->indexOf(devDesc);
429 if (index >= 0) {
430 return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
431 } else {
432 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
433 }
Eric Laurente552edb2014-03-10 17:42:56 -0700434}
435
Eric Laurentc2730ba2014-07-20 15:47:07 -0700436void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs)
437{
438 bool createTxPatch = false;
439 struct audio_patch patch;
440 patch.num_sources = 1;
441 patch.num_sinks = 1;
442 status_t status;
443 audio_patch_handle_t afPatchHandle;
444 DeviceVector deviceList;
445
446 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
447 ALOGV("updateCallRouting device rxDevice %08x txDevice %08x", rxDevice, txDevice);
448
449 // release existing RX patch if any
450 if (mCallRxPatch != 0) {
451 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
452 mCallRxPatch.clear();
453 }
454 // release TX patch if any
455 if (mCallTxPatch != 0) {
456 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
457 mCallTxPatch.clear();
458 }
459
460 // If the RX device is on the primary HW module, then use legacy routing method for voice calls
461 // via setOutputDevice() on primary output.
462 // Otherwise, create two audio patches for TX and RX path.
463 if (availablePrimaryOutputDevices() & rxDevice) {
464 setOutputDevice(mPrimaryOutput, rxDevice, true, delayMs);
465 // If the TX device is also on the primary HW module, setOutputDevice() will take care
466 // of it due to legacy implementation. If not, create a patch.
467 if ((availablePrimaryInputDevices() & txDevice & ~AUDIO_DEVICE_BIT_IN)
468 == AUDIO_DEVICE_NONE) {
469 createTxPatch = true;
470 }
471 } else {
472 // create RX path audio patch
473 deviceList = mAvailableOutputDevices.getDevicesFromType(rxDevice);
474 ALOG_ASSERT(!deviceList.isEmpty(),
475 "updateCallRouting() selected device not in output device list");
476 sp<DeviceDescriptor> rxSinkDeviceDesc = deviceList.itemAt(0);
477 deviceList = mAvailableInputDevices.getDevicesFromType(AUDIO_DEVICE_IN_TELEPHONY_RX);
478 ALOG_ASSERT(!deviceList.isEmpty(),
479 "updateCallRouting() no telephony RX device");
480 sp<DeviceDescriptor> rxSourceDeviceDesc = deviceList.itemAt(0);
481
482 rxSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
483 rxSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
484
485 // request to reuse existing output stream if one is already opened to reach the RX device
486 SortedVector<audio_io_handle_t> outputs =
487 getOutputsForDevice(rxDevice, mOutputs);
488 audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE);
489 if (output != AUDIO_IO_HANDLE_NONE) {
490 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
491 ALOG_ASSERT(!outputDesc->isDuplicated(),
492 "updateCallRouting() RX device output is duplicated");
493 outputDesc->toAudioPortConfig(&patch.sources[1]);
494 patch.num_sources = 2;
495 }
496
497 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
498 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
499 ALOGW_IF(status != NO_ERROR, "updateCallRouting() error %d creating RX audio patch",
500 status);
501 if (status == NO_ERROR) {
502 mCallRxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
503 &patch, mUidCached);
504 mCallRxPatch->mAfPatchHandle = afPatchHandle;
505 mCallRxPatch->mUid = mUidCached;
506 }
507 createTxPatch = true;
508 }
509 if (createTxPatch) {
510
511 struct audio_patch patch;
512 patch.num_sources = 1;
513 patch.num_sinks = 1;
514 deviceList = mAvailableInputDevices.getDevicesFromType(txDevice);
515 ALOG_ASSERT(!deviceList.isEmpty(),
516 "updateCallRouting() selected device not in input device list");
517 sp<DeviceDescriptor> txSourceDeviceDesc = deviceList.itemAt(0);
518 txSourceDeviceDesc->toAudioPortConfig(&patch.sources[0]);
519 deviceList = mAvailableOutputDevices.getDevicesFromType(AUDIO_DEVICE_OUT_TELEPHONY_TX);
520 ALOG_ASSERT(!deviceList.isEmpty(),
521 "updateCallRouting() no telephony TX device");
522 sp<DeviceDescriptor> txSinkDeviceDesc = deviceList.itemAt(0);
523 txSinkDeviceDesc->toAudioPortConfig(&patch.sinks[0]);
524
525 SortedVector<audio_io_handle_t> outputs =
526 getOutputsForDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, mOutputs);
527 audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE);
528 // request to reuse existing output stream if one is already opened to reach the TX
529 // path output device
530 if (output != AUDIO_IO_HANDLE_NONE) {
531 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
532 ALOG_ASSERT(!outputDesc->isDuplicated(),
533 "updateCallRouting() RX device output is duplicated");
534 outputDesc->toAudioPortConfig(&patch.sources[1]);
535 patch.num_sources = 2;
536 }
537
538 afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
539 status = mpClientInterface->createAudioPatch(&patch, &afPatchHandle, 0);
540 ALOGW_IF(status != NO_ERROR, "setPhoneState() error %d creating TX audio patch",
541 status);
542 if (status == NO_ERROR) {
543 mCallTxPatch = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
544 &patch, mUidCached);
545 mCallTxPatch->mAfPatchHandle = afPatchHandle;
546 mCallTxPatch->mUid = mUidCached;
547 }
548 }
549}
550
Eric Laurente0720872014-03-11 09:30:41 -0700551void AudioPolicyManager::setPhoneState(audio_mode_t state)
Eric Laurente552edb2014-03-10 17:42:56 -0700552{
553 ALOGV("setPhoneState() state %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700554 if (state < 0 || state >= AUDIO_MODE_CNT) {
Eric Laurente552edb2014-03-10 17:42:56 -0700555 ALOGW("setPhoneState() invalid state %d", state);
556 return;
557 }
558
559 if (state == mPhoneState ) {
560 ALOGW("setPhoneState() setting same state %d", state);
561 return;
562 }
563
564 // if leaving call state, handle special case of active streams
565 // pertaining to sonification strategy see handleIncallSonification()
566 if (isInCall()) {
567 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700568 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
569 handleIncallSonification((audio_stream_type_t)stream, false, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700570 }
571 }
572
573 // store previous phone state for management of sonification strategy below
574 int oldState = mPhoneState;
575 mPhoneState = state;
576 bool force = false;
577
578 // are we entering or starting a call
579 if (!isStateInCall(oldState) && isStateInCall(state)) {
580 ALOGV(" Entering call in setPhoneState()");
581 // force routing command to audio hardware when starting a call
582 // even if no device change is needed
583 force = true;
584 for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
585 mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
586 sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j];
587 }
588 } else if (isStateInCall(oldState) && !isStateInCall(state)) {
589 ALOGV(" Exiting call in setPhoneState()");
590 // force routing command to audio hardware when exiting a call
591 // even if no device change is needed
592 force = true;
593 for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
594 mStreams[AUDIO_STREAM_DTMF].mVolumeCurve[j] =
595 sVolumeProfiles[AUDIO_STREAM_DTMF][j];
596 }
597 } else if (isStateInCall(state) && (state != oldState)) {
598 ALOGV(" Switching between telephony and VoIP in setPhoneState()");
599 // force routing command to audio hardware when switching between telephony and VoIP
600 // even if no device change is needed
601 force = true;
602 }
603
604 // check for device and output changes triggered by new phone state
Eric Laurente552edb2014-03-10 17:42:56 -0700605 checkA2dpSuspend();
606 checkOutputForAllStrategies();
607 updateDevicesAndOutputs();
608
Eric Laurent1f2f2232014-06-02 12:01:23 -0700609 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -0700610
Eric Laurente552edb2014-03-10 17:42:56 -0700611 int delayMs = 0;
612 if (isStateInCall(state)) {
613 nsecs_t sysTime = systemTime();
614 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700615 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700616 // mute media and sonification strategies and delay device switch by the largest
617 // latency of any output where either strategy is active.
618 // This avoid sending the ring tone or music tail into the earpiece or headset.
619 if ((desc->isStrategyActive(STRATEGY_MEDIA,
620 SONIFICATION_HEADSET_MUSIC_DELAY,
621 sysTime) ||
622 desc->isStrategyActive(STRATEGY_SONIFICATION,
623 SONIFICATION_HEADSET_MUSIC_DELAY,
624 sysTime)) &&
625 (delayMs < (int)desc->mLatency*2)) {
626 delayMs = desc->mLatency*2;
627 }
628 setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
629 setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
630 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
631 setStrategyMute(STRATEGY_SONIFICATION, true, mOutputs.keyAt(i));
632 setStrategyMute(STRATEGY_SONIFICATION, false, mOutputs.keyAt(i), MUTE_TIME_MS,
633 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
634 }
635 }
636
Eric Laurentc2730ba2014-07-20 15:47:07 -0700637 // Note that despite the fact that getNewOutputDevice() is called on the primary output,
638 // the device returned is not necessarily reachable via this output
639 audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
640 // force routing command to audio hardware when ending call
641 // even if no device change is needed
642 if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
643 rxDevice = hwOutputDesc->device();
644 }
Eric Laurente552edb2014-03-10 17:42:56 -0700645
Eric Laurentc2730ba2014-07-20 15:47:07 -0700646 if (state == AUDIO_MODE_IN_CALL) {
647 updateCallRouting(rxDevice, delayMs);
648 } else if (oldState == AUDIO_MODE_IN_CALL) {
649 if (mCallRxPatch != 0) {
650 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
651 mCallRxPatch.clear();
652 }
653 if (mCallTxPatch != 0) {
654 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
655 mCallTxPatch.clear();
656 }
657 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
658 } else {
659 setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
660 }
Eric Laurente552edb2014-03-10 17:42:56 -0700661 // if entering in call state, handle special case of active streams
662 // pertaining to sonification strategy see handleIncallSonification()
663 if (isStateInCall(state)) {
664 ALOGV("setPhoneState() in call state management: new state is %d", state);
Eric Laurent3b73df72014-03-11 09:06:29 -0700665 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
666 handleIncallSonification((audio_stream_type_t)stream, true, true);
Eric Laurente552edb2014-03-10 17:42:56 -0700667 }
668 }
669
670 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
Eric Laurent3b73df72014-03-11 09:06:29 -0700671 if (state == AUDIO_MODE_RINGTONE &&
672 isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700673 mLimitRingtoneVolume = true;
674 } else {
675 mLimitRingtoneVolume = false;
676 }
677}
678
Eric Laurente0720872014-03-11 09:30:41 -0700679void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
Eric Laurent3b73df72014-03-11 09:06:29 -0700680 audio_policy_forced_cfg_t config)
Eric Laurente552edb2014-03-10 17:42:56 -0700681{
682 ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
683
684 bool forceVolumeReeval = false;
685 switch(usage) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700686 case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
687 if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
688 config != AUDIO_POLICY_FORCE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -0700689 ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
690 return;
691 }
692 forceVolumeReeval = true;
693 mForceUse[usage] = config;
694 break;
Eric Laurent3b73df72014-03-11 09:06:29 -0700695 case AUDIO_POLICY_FORCE_FOR_MEDIA:
696 if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
697 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
698 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
699 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
Jungshik Jang0c943092014-07-08 22:11:24 +0900700 config != AUDIO_POLICY_FORCE_NO_BT_A2DP) {
Eric Laurente552edb2014-03-10 17:42:56 -0700701 ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
702 return;
703 }
704 mForceUse[usage] = config;
705 break;
Eric Laurent3b73df72014-03-11 09:06:29 -0700706 case AUDIO_POLICY_FORCE_FOR_RECORD:
707 if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
708 config != AUDIO_POLICY_FORCE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -0700709 ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
710 return;
711 }
712 mForceUse[usage] = config;
713 break;
Eric Laurent3b73df72014-03-11 09:06:29 -0700714 case AUDIO_POLICY_FORCE_FOR_DOCK:
715 if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
716 config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
717 config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
718 config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
719 config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
Eric Laurente552edb2014-03-10 17:42:56 -0700720 ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
721 }
722 forceVolumeReeval = true;
723 mForceUse[usage] = config;
724 break;
Eric Laurent3b73df72014-03-11 09:06:29 -0700725 case AUDIO_POLICY_FORCE_FOR_SYSTEM:
726 if (config != AUDIO_POLICY_FORCE_NONE &&
727 config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
Eric Laurente552edb2014-03-10 17:42:56 -0700728 ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
729 }
730 forceVolumeReeval = true;
731 mForceUse[usage] = config;
732 break;
Jungshik Jang7b24ee32014-07-15 19:38:42 +0900733 case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
734 if (config != AUDIO_POLICY_FORCE_NONE &&
735 config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
736 ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config);
737 }
738 mForceUse[usage] = config;
739 break;
Eric Laurente552edb2014-03-10 17:42:56 -0700740 default:
741 ALOGW("setForceUse() invalid usage %d", usage);
742 break;
743 }
744
745 // check for device and output changes triggered by new force usage
746 checkA2dpSuspend();
747 checkOutputForAllStrategies();
748 updateDevicesAndOutputs();
Eric Laurentc2730ba2014-07-20 15:47:07 -0700749 if (mPhoneState == AUDIO_MODE_IN_CALL) {
750 audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
751 updateCallRouting(newDevice);
752 }
Eric Laurente552edb2014-03-10 17:42:56 -0700753 for (size_t i = 0; i < mOutputs.size(); i++) {
754 audio_io_handle_t output = mOutputs.keyAt(i);
Eric Laurent1c333e22014-05-20 10:48:17 -0700755 audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
Eric Laurentc2730ba2014-07-20 15:47:07 -0700756 if ((mPhoneState != AUDIO_MODE_IN_CALL) || (output != mPrimaryOutput)) {
757 setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
758 }
Eric Laurente552edb2014-03-10 17:42:56 -0700759 if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
760 applyStreamVolumes(output, newDevice, 0, true);
761 }
762 }
763
764 audio_io_handle_t activeInput = getActiveInput();
765 if (activeInput != 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700766 setInputDevice(activeInput, getNewInputDevice(activeInput));
Eric Laurente552edb2014-03-10 17:42:56 -0700767 }
768
769}
770
Eric Laurente0720872014-03-11 09:30:41 -0700771audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
Eric Laurente552edb2014-03-10 17:42:56 -0700772{
773 return mForceUse[usage];
774}
775
Eric Laurente0720872014-03-11 09:30:41 -0700776void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
Eric Laurente552edb2014-03-10 17:42:56 -0700777{
778 ALOGV("setSystemProperty() property %s, value %s", property, value);
779}
780
781// Find a direct output profile compatible with the parameters passed, even if the input flags do
782// not explicitly request a direct output
Eric Laurent1c333e22014-05-20 10:48:17 -0700783sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput(
Eric Laurente552edb2014-03-10 17:42:56 -0700784 audio_devices_t device,
785 uint32_t samplingRate,
786 audio_format_t format,
787 audio_channel_mask_t channelMask,
788 audio_output_flags_t flags)
789{
790 for (size_t i = 0; i < mHwModules.size(); i++) {
791 if (mHwModules[i]->mHandle == 0) {
792 continue;
793 }
794 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700795 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
Glenn Kastencbd48022014-07-24 13:46:44 -0700796 bool found = profile->isCompatibleProfile(device, samplingRate,
797 NULL /*updatedSamplingRate*/, format, channelMask,
798 flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD ?
799 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurent3a4311c2014-03-17 12:00:47 -0700800 if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
801 return profile;
802 }
Eric Laurente552edb2014-03-10 17:42:56 -0700803 }
804 }
805 return 0;
806}
807
Eric Laurente0720872014-03-11 09:30:41 -0700808audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -0700809 uint32_t samplingRate,
810 audio_format_t format,
811 audio_channel_mask_t channelMask,
Eric Laurent3b73df72014-03-11 09:06:29 -0700812 audio_output_flags_t flags,
Eric Laurente552edb2014-03-10 17:42:56 -0700813 const audio_offload_info_t *offloadInfo)
814{
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700815
Eric Laurent3b73df72014-03-11 09:06:29 -0700816 routing_strategy strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -0700817 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
818 ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
819 device, stream, samplingRate, format, channelMask, flags);
820
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700821 return getOutputForDevice(device, stream, samplingRate,format, channelMask, flags,
822 offloadInfo);
823}
824
825audio_io_handle_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
826 uint32_t samplingRate,
827 audio_format_t format,
828 audio_channel_mask_t channelMask,
829 audio_output_flags_t flags,
830 const audio_offload_info_t *offloadInfo)
831{
832 if (attr == NULL) {
833 ALOGE("getOutputForAttr() called with NULL audio attributes");
834 return 0;
835 }
Eric Laurent93c3d412014-08-01 14:48:35 -0700836 ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x",
837 attr->usage, attr->content_type, attr->tags, attr->flags);
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700838
839 // TODO this is where filtering for custom policies (rerouting, dynamic sources) will go
840 routing_strategy strategy = (routing_strategy) getStrategyForAttr(attr);
841 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
Eric Laurent93c3d412014-08-01 14:48:35 -0700842
843 if ((attr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
844 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
845 }
846
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700847 ALOGV("getOutputForAttr() device %d, samplingRate %d, format %x, channelMask %x, flags %x",
848 device, samplingRate, format, channelMask, flags);
849
850 audio_stream_type_t stream = streamTypefromAttributesInt(attr);
851 return getOutputForDevice(device, stream, samplingRate, format, channelMask, flags,
852 offloadInfo);
853}
854
855audio_io_handle_t AudioPolicyManager::getOutputForDevice(
856 audio_devices_t device,
857 audio_stream_type_t stream,
858 uint32_t samplingRate,
859 audio_format_t format,
860 audio_channel_mask_t channelMask,
861 audio_output_flags_t flags,
862 const audio_offload_info_t *offloadInfo)
863{
Eric Laurentcf2c0212014-07-25 16:20:43 -0700864 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700865 uint32_t latency = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700866 status_t status;
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -0700867
Eric Laurente552edb2014-03-10 17:42:56 -0700868#ifdef AUDIO_POLICY_TEST
869 if (mCurOutput != 0) {
870 ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
871 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
872
873 if (mTestOutputs[mCurOutput] == 0) {
874 ALOGV("getOutput() opening test output");
Eric Laurent1f2f2232014-06-02 12:01:23 -0700875 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
Eric Laurente552edb2014-03-10 17:42:56 -0700876 outputDesc->mDevice = mTestDevice;
Eric Laurente552edb2014-03-10 17:42:56 -0700877 outputDesc->mLatency = mTestLatencyMs;
Eric Laurent3b73df72014-03-11 09:06:29 -0700878 outputDesc->mFlags =
879 (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
Eric Laurente552edb2014-03-10 17:42:56 -0700880 outputDesc->mRefCount[stream] = 0;
Eric Laurentcf2c0212014-07-25 16:20:43 -0700881 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
882 config.sample_rate = mTestSamplingRate;
883 config.channel_mask = mTestChannels;
884 config.format = mTestFormat;
Phil Burk77cce802014-08-04 16:18:15 -0700885 if (offloadInfo != NULL) {
886 config.offload_info = *offloadInfo;
887 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700888 status = mpClientInterface->openOutput(0,
889 &mTestOutputs[mCurOutput],
890 &config,
891 &outputDesc->mDevice,
892 String8(""),
893 &outputDesc->mLatency,
894 outputDesc->mFlags);
895 if (status == NO_ERROR) {
896 outputDesc->mSamplingRate = config.sample_rate;
897 outputDesc->mFormat = config.format;
898 outputDesc->mChannelMask = config.channel_mask;
Eric Laurente552edb2014-03-10 17:42:56 -0700899 AudioParameter outputCmd = AudioParameter();
900 outputCmd.addInt(String8("set_id"),mCurOutput);
901 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
902 addOutput(mTestOutputs[mCurOutput], outputDesc);
903 }
904 }
905 return mTestOutputs[mCurOutput];
906 }
907#endif //AUDIO_POLICY_TEST
908
909 // open a direct output if required by specified parameters
910 //force direct flag if offload flag is set: offloading implies a direct output stream
911 // and all common behaviors are driven by checking only the direct flag
912 // this should normally be set appropriately in the policy configuration file
913 if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
Eric Laurent3b73df72014-03-11 09:06:29 -0700914 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
Eric Laurente552edb2014-03-10 17:42:56 -0700915 }
Eric Laurent93c3d412014-08-01 14:48:35 -0700916 if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
917 flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
918 }
Eric Laurente552edb2014-03-10 17:42:56 -0700919
920 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
921 // creating an offloaded track and tearing it down immediately after start when audioflinger
922 // detects there is an active non offloadable effect.
923 // FIXME: We should check the audio session here but we do not have it in this context.
924 // This may prevent offloading in rare situations where effects are left active by apps
925 // in the background.
Eric Laurent1c333e22014-05-20 10:48:17 -0700926 sp<IOProfile> profile;
Eric Laurente552edb2014-03-10 17:42:56 -0700927 if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
928 !isNonOffloadableEffectEnabled()) {
929 profile = getProfileForDirectOutput(device,
930 samplingRate,
931 format,
932 channelMask,
933 (audio_output_flags_t)flags);
934 }
935
Eric Laurent1c333e22014-05-20 10:48:17 -0700936 if (profile != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700937 sp<AudioOutputDescriptor> outputDesc = NULL;
Eric Laurente552edb2014-03-10 17:42:56 -0700938
939 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -0700940 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -0700941 if (!desc->isDuplicated() && (profile == desc->mProfile)) {
942 outputDesc = desc;
943 // reuse direct output if currently open and configured with same parameters
944 if ((samplingRate == outputDesc->mSamplingRate) &&
945 (format == outputDesc->mFormat) &&
946 (channelMask == outputDesc->mChannelMask)) {
947 outputDesc->mDirectOpenCount++;
948 ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
949 return mOutputs.keyAt(i);
950 }
951 }
952 }
953 // close direct output if currently open and configured with different parameters
954 if (outputDesc != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -0700955 closeOutput(outputDesc->mIoHandle);
Eric Laurente552edb2014-03-10 17:42:56 -0700956 }
957 outputDesc = new AudioOutputDescriptor(profile);
958 outputDesc->mDevice = device;
Eric Laurente552edb2014-03-10 17:42:56 -0700959 outputDesc->mLatency = 0;
960 outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700961 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
962 config.sample_rate = samplingRate;
963 config.channel_mask = channelMask;
964 config.format = format;
Phil Burk77cce802014-08-04 16:18:15 -0700965 if (offloadInfo != NULL) {
966 config.offload_info = *offloadInfo;
967 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700968 status = mpClientInterface->openOutput(profile->mModule->mHandle,
969 &output,
970 &config,
971 &outputDesc->mDevice,
972 String8(""),
973 &outputDesc->mLatency,
974 outputDesc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -0700975
976 // only accept an output with the requested parameters
Eric Laurentcf2c0212014-07-25 16:20:43 -0700977 if (status != NO_ERROR ||
978 (samplingRate != 0 && samplingRate != config.sample_rate) ||
979 (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
980 (channelMask != 0 && channelMask != config.channel_mask)) {
Eric Laurente552edb2014-03-10 17:42:56 -0700981 ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
982 "format %d %d, channelMask %04x %04x", output, samplingRate,
983 outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
984 outputDesc->mChannelMask);
Eric Laurentcf2c0212014-07-25 16:20:43 -0700985 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -0700986 mpClientInterface->closeOutput(output);
987 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700988 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -0700989 }
Eric Laurentcf2c0212014-07-25 16:20:43 -0700990 outputDesc->mSamplingRate = config.sample_rate;
991 outputDesc->mChannelMask = config.channel_mask;
992 outputDesc->mFormat = config.format;
993 outputDesc->mRefCount[stream] = 0;
994 outputDesc->mStopTime[stream] = 0;
995 outputDesc->mDirectOpenCount = 1;
996
Eric Laurente552edb2014-03-10 17:42:56 -0700997 audio_io_handle_t srcOutput = getOutputForEffect();
998 addOutput(output, outputDesc);
999 audio_io_handle_t dstOutput = getOutputForEffect();
1000 if (dstOutput == output) {
1001 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
1002 }
1003 mPreviousOutputs = mOutputs;
1004 ALOGV("getOutput() returns new direct output %d", output);
Eric Laurentb52c1522014-05-20 11:27:36 -07001005 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001006 return output;
1007 }
1008
1009 // ignoring channel mask due to downmix capability in mixer
1010
1011 // open a non direct output
1012
1013 // for non direct outputs, only PCM is supported
1014 if (audio_is_linear_pcm(format)) {
1015 // get which output is suitable for the specified stream. The actual
1016 // routing change will happen when startOutput() will be called
1017 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1018
1019 output = selectOutput(outputs, flags);
1020 }
1021 ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1022 "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1023
1024 ALOGV("getOutput() returns output %d", output);
1025
1026 return output;
1027}
1028
Eric Laurente0720872014-03-11 09:30:41 -07001029audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
Eric Laurent3b73df72014-03-11 09:06:29 -07001030 audio_output_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07001031{
1032 // select one output among several that provide a path to a particular device or set of
1033 // devices (the list was previously build by getOutputsForDevice()).
1034 // The priority is as follows:
1035 // 1: the output with the highest number of requested policy flags
1036 // 2: the primary output
1037 // 3: the first output in the list
1038
1039 if (outputs.size() == 0) {
1040 return 0;
1041 }
1042 if (outputs.size() == 1) {
1043 return outputs[0];
1044 }
1045
1046 int maxCommonFlags = 0;
1047 audio_io_handle_t outputFlags = 0;
1048 audio_io_handle_t outputPrimary = 0;
1049
1050 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001051 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -07001052 if (!outputDesc->isDuplicated()) {
Eric Laurent3b73df72014-03-11 09:06:29 -07001053 int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001054 if (commonFlags > maxCommonFlags) {
1055 outputFlags = outputs[i];
1056 maxCommonFlags = commonFlags;
1057 ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
1058 }
1059 if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
1060 outputPrimary = outputs[i];
1061 }
1062 }
1063 }
1064
1065 if (outputFlags != 0) {
1066 return outputFlags;
1067 }
1068 if (outputPrimary != 0) {
1069 return outputPrimary;
1070 }
1071
1072 return outputs[0];
1073}
1074
Eric Laurente0720872014-03-11 09:30:41 -07001075status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001076 audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001077 int session)
1078{
1079 ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
1080 ssize_t index = mOutputs.indexOfKey(output);
1081 if (index < 0) {
1082 ALOGW("startOutput() unknown output %d", output);
1083 return BAD_VALUE;
1084 }
1085
Eric Laurent1f2f2232014-06-02 12:01:23 -07001086 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001087
1088 // increment usage count for this stream on the requested output:
1089 // NOTE that the usage count is the same for duplicated output and hardware output which is
1090 // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1091 outputDesc->changeRefCount(stream, 1);
1092
1093 if (outputDesc->mRefCount[stream] == 1) {
Eric Laurent1c333e22014-05-20 10:48:17 -07001094 audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
Eric Laurente552edb2014-03-10 17:42:56 -07001095 routing_strategy strategy = getStrategy(stream);
1096 bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
1097 (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
1098 uint32_t waitMs = 0;
1099 bool force = false;
1100 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001101 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001102 if (desc != outputDesc) {
1103 // force a device change if any other output is managed by the same hw
1104 // module and has a current device selection that differs from selected device.
1105 // In this case, the audio HAL must receive the new device selection so that it can
1106 // change the device currently selected by the other active output.
1107 if (outputDesc->sharesHwModuleWith(desc) &&
1108 desc->device() != newDevice) {
1109 force = true;
1110 }
1111 // wait for audio on other active outputs to be presented when starting
1112 // a notification so that audio focus effect can propagate.
1113 uint32_t latency = desc->latency();
1114 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1115 waitMs = latency;
1116 }
1117 }
1118 }
1119 uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
1120
1121 // handle special case for sonification while in call
1122 if (isInCall()) {
1123 handleIncallSonification(stream, true, false);
1124 }
1125
1126 // apply volume rules for current stream and device if necessary
1127 checkAndSetVolume(stream,
1128 mStreams[stream].getVolumeIndex(newDevice),
1129 output,
1130 newDevice);
1131
1132 // update the outputs if starting an output with a stream that can affect notification
1133 // routing
1134 handleNotificationRoutingForStream(stream);
1135 if (waitMs > muteWaitMs) {
1136 usleep((waitMs - muteWaitMs) * 2 * 1000);
1137 }
1138 }
1139 return NO_ERROR;
1140}
1141
1142
Eric Laurente0720872014-03-11 09:30:41 -07001143status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
Eric Laurent3b73df72014-03-11 09:06:29 -07001144 audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001145 int session)
1146{
1147 ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
1148 ssize_t index = mOutputs.indexOfKey(output);
1149 if (index < 0) {
1150 ALOGW("stopOutput() unknown output %d", output);
1151 return BAD_VALUE;
1152 }
1153
Eric Laurent1f2f2232014-06-02 12:01:23 -07001154 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001155
1156 // handle special case for sonification while in call
1157 if (isInCall()) {
1158 handleIncallSonification(stream, false, false);
1159 }
1160
1161 if (outputDesc->mRefCount[stream] > 0) {
1162 // decrement usage count of this stream on the output
1163 outputDesc->changeRefCount(stream, -1);
1164 // store time at which the stream was stopped - see isStreamActive()
1165 if (outputDesc->mRefCount[stream] == 0) {
1166 outputDesc->mStopTime[stream] = systemTime();
Eric Laurent1c333e22014-05-20 10:48:17 -07001167 audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
Eric Laurente552edb2014-03-10 17:42:56 -07001168 // delay the device switch by twice the latency because stopOutput() is executed when
1169 // the track stop() command is received and at that time the audio track buffer can
1170 // still contain data that needs to be drained. The latency only covers the audio HAL
1171 // and kernel buffers. Also the latency does not always include additional delay in the
1172 // audio path (audio DSP, CODEC ...)
1173 setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
1174
1175 // force restoring the device selection on other active outputs if it differs from the
1176 // one being selected for this output
1177 for (size_t i = 0; i < mOutputs.size(); i++) {
1178 audio_io_handle_t curOutput = mOutputs.keyAt(i);
Eric Laurent1f2f2232014-06-02 12:01:23 -07001179 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001180 if (curOutput != output &&
1181 desc->isActive() &&
1182 outputDesc->sharesHwModuleWith(desc) &&
1183 (newDevice != desc->device())) {
1184 setOutputDevice(curOutput,
Eric Laurent1c333e22014-05-20 10:48:17 -07001185 getNewOutputDevice(curOutput, false /*fromCache*/),
Eric Laurente552edb2014-03-10 17:42:56 -07001186 true,
1187 outputDesc->mLatency*2);
1188 }
1189 }
1190 // update the outputs if stopping one with a stream that can affect notification routing
1191 handleNotificationRoutingForStream(stream);
1192 }
1193 return NO_ERROR;
1194 } else {
1195 ALOGW("stopOutput() refcount is already 0 for output %d", output);
1196 return INVALID_OPERATION;
1197 }
1198}
1199
Eric Laurente0720872014-03-11 09:30:41 -07001200void AudioPolicyManager::releaseOutput(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07001201{
1202 ALOGV("releaseOutput() %d", output);
1203 ssize_t index = mOutputs.indexOfKey(output);
1204 if (index < 0) {
1205 ALOGW("releaseOutput() releasing unknown output %d", output);
1206 return;
1207 }
1208
1209#ifdef AUDIO_POLICY_TEST
1210 int testIndex = testOutputIndex(output);
1211 if (testIndex != 0) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001212 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001213 if (outputDesc->isActive()) {
1214 mpClientInterface->closeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07001215 mOutputs.removeItem(output);
1216 mTestOutputs[testIndex] = 0;
1217 }
1218 return;
1219 }
1220#endif //AUDIO_POLICY_TEST
1221
Eric Laurent1f2f2232014-06-02 12:01:23 -07001222 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(index);
Eric Laurent3b73df72014-03-11 09:06:29 -07001223 if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
Eric Laurente552edb2014-03-10 17:42:56 -07001224 if (desc->mDirectOpenCount <= 0) {
1225 ALOGW("releaseOutput() invalid open count %d for output %d",
1226 desc->mDirectOpenCount, output);
1227 return;
1228 }
1229 if (--desc->mDirectOpenCount == 0) {
1230 closeOutput(output);
1231 // If effects where present on the output, audioflinger moved them to the primary
1232 // output by default: move them back to the appropriate output.
1233 audio_io_handle_t dstOutput = getOutputForEffect();
1234 if (dstOutput != mPrimaryOutput) {
1235 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
1236 }
Eric Laurentb52c1522014-05-20 11:27:36 -07001237 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001238 }
1239 }
1240}
1241
1242
Eric Laurente0720872014-03-11 09:30:41 -07001243audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
Eric Laurente552edb2014-03-10 17:42:56 -07001244 uint32_t samplingRate,
1245 audio_format_t format,
1246 audio_channel_mask_t channelMask,
Eric Laurent4dc68062014-07-28 17:26:49 -07001247 audio_session_t session,
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001248 audio_input_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07001249{
Eric Laurent4dc68062014-07-28 17:26:49 -07001250 ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001251 "flags %#x",
Eric Laurent4dc68062014-07-28 17:26:49 -07001252 inputSource, samplingRate, format, channelMask, session, flags);
Eric Laurente552edb2014-03-10 17:42:56 -07001253
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001254 audio_devices_t device = getDeviceForInputSource(inputSource);
Eric Laurente552edb2014-03-10 17:42:56 -07001255
1256 if (device == AUDIO_DEVICE_NONE) {
1257 ALOGW("getInput() could not find device for inputSource %d", inputSource);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001258 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001259 }
1260
1261 // adapt channel selection to input source
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001262 switch (inputSource) {
Eric Laurente552edb2014-03-10 17:42:56 -07001263 case AUDIO_SOURCE_VOICE_UPLINK:
1264 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
1265 break;
1266 case AUDIO_SOURCE_VOICE_DOWNLINK:
1267 channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
1268 break;
1269 case AUDIO_SOURCE_VOICE_CALL:
1270 channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
1271 break;
1272 default:
1273 break;
1274 }
1275
Eric Laurent1c333e22014-05-20 10:48:17 -07001276 sp<IOProfile> profile = getInputProfile(device,
Eric Laurente552edb2014-03-10 17:42:56 -07001277 samplingRate,
1278 format,
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001279 channelMask,
1280 flags);
Eric Laurent1c333e22014-05-20 10:48:17 -07001281 if (profile == 0) {
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001282 ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, "
1283 "channelMask 0x%X, flags %#x",
1284 device, samplingRate, format, channelMask, flags);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001285 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001286 }
1287
1288 if (profile->mModule->mHandle == 0) {
1289 ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
Eric Laurentcf2c0212014-07-25 16:20:43 -07001290 return AUDIO_IO_HANDLE_NONE;
1291 }
1292
1293 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1294 config.sample_rate = samplingRate;
1295 config.channel_mask = channelMask;
1296 config.format = format;
1297 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001298
1299 bool isSoundTrigger = false;
1300 if (inputSource == AUDIO_SOURCE_HOTWORD) {
1301 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
1302 if (index >= 0) {
1303 input = mSoundTriggerSessions.valueFor(session);
1304 isSoundTrigger = true;
1305 ALOGV("SoundTrigger capture on session %d input %d", session, input);
1306 }
1307 }
1308
Eric Laurentcf2c0212014-07-25 16:20:43 -07001309 status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
1310 &input,
1311 &config,
1312 &device,
1313 String8(""),
1314 inputSource,
1315 flags);
1316
1317 // only accept input with the exact requested set of parameters
1318 if (status != NO_ERROR ||
1319 (samplingRate != config.sample_rate) ||
1320 (format != config.format) ||
1321 (channelMask != config.channel_mask)) {
1322 ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
1323 samplingRate, format, channelMask);
1324 if (input != AUDIO_IO_HANDLE_NONE) {
1325 mpClientInterface->closeInput(input);
1326 }
1327 return AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07001328 }
1329
Eric Laurent1f2f2232014-06-02 12:01:23 -07001330 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
Eric Laurente552edb2014-03-10 17:42:56 -07001331 inputDesc->mInputSource = inputSource;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001332 inputDesc->mRefCount = 0;
1333 inputDesc->mOpenRefCount = 1;
Eric Laurente552edb2014-03-10 17:42:56 -07001334 inputDesc->mSamplingRate = samplingRate;
1335 inputDesc->mFormat = format;
1336 inputDesc->mChannelMask = channelMask;
Eric Laurentcf2c0212014-07-25 16:20:43 -07001337 inputDesc->mDevice = device;
Eric Laurent4dc68062014-07-28 17:26:49 -07001338 inputDesc->mSessions.add(session);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001339 inputDesc->mIsSoundTrigger = isSoundTrigger;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001340
Eric Laurentd4692962014-05-05 18:13:44 -07001341 addInput(input, inputDesc);
Eric Laurentb52c1522014-05-20 11:27:36 -07001342 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001343 return input;
1344}
1345
Eric Laurent4dc68062014-07-28 17:26:49 -07001346status_t AudioPolicyManager::startInput(audio_io_handle_t input,
1347 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001348{
1349 ALOGV("startInput() input %d", input);
1350 ssize_t index = mInputs.indexOfKey(input);
1351 if (index < 0) {
1352 ALOGW("startInput() unknown input %d", input);
1353 return BAD_VALUE;
1354 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001355 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001356
Eric Laurent4dc68062014-07-28 17:26:49 -07001357 index = inputDesc->mSessions.indexOf(session);
1358 if (index < 0) {
1359 ALOGW("startInput() unknown session %d on input %d", session, input);
1360 return BAD_VALUE;
1361 }
1362
Glenn Kasten74a8e252014-07-24 14:09:55 -07001363 // virtual input devices are compatible with other input devices
1364 if (!isVirtualInputDevice(inputDesc->mDevice)) {
1365
1366 // for a non-virtual input device, check if there is another (non-virtual) active input
Eric Laurente552edb2014-03-10 17:42:56 -07001367 audio_io_handle_t activeInput = getActiveInput();
Glenn Kasten74a8e252014-07-24 14:09:55 -07001368 if (activeInput != 0 && activeInput != input) {
1369
1370 // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1371 // otherwise the active input continues and the new input cannot be started.
Eric Laurent1f2f2232014-06-02 12:01:23 -07001372 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
Eric Laurente552edb2014-03-10 17:42:56 -07001373 if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001374 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
Eric Laurent4dc68062014-07-28 17:26:49 -07001375 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
1376 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
Eric Laurente552edb2014-03-10 17:42:56 -07001377 } else {
Glenn Kasten74a8e252014-07-24 14:09:55 -07001378 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
Eric Laurente552edb2014-03-10 17:42:56 -07001379 return INVALID_OPERATION;
1380 }
1381 }
1382 }
1383
Glenn Kasten74a8e252014-07-24 14:09:55 -07001384 if (inputDesc->mRefCount == 0) {
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001385 if (activeInputsCount() == 0) {
1386 SoundTrigger::setCaptureState(true);
1387 }
Glenn Kasten74a8e252014-07-24 14:09:55 -07001388 setInputDevice(input, getNewInputDevice(input), true /* force */);
Eric Laurente552edb2014-03-10 17:42:56 -07001389
Glenn Kasten74a8e252014-07-24 14:09:55 -07001390 // Automatically enable the remote submix output when input is started.
1391 // For remote submix (a virtual device), we open only one input per capture request.
1392 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1393 setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1394 AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
1395 }
Eric Laurente552edb2014-03-10 17:42:56 -07001396 }
1397
Eric Laurente552edb2014-03-10 17:42:56 -07001398 ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1399
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001400 inputDesc->mRefCount++;
Eric Laurente552edb2014-03-10 17:42:56 -07001401 return NO_ERROR;
1402}
1403
Eric Laurent4dc68062014-07-28 17:26:49 -07001404status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
1405 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001406{
1407 ALOGV("stopInput() input %d", input);
1408 ssize_t index = mInputs.indexOfKey(input);
1409 if (index < 0) {
1410 ALOGW("stopInput() unknown input %d", input);
1411 return BAD_VALUE;
1412 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001413 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001414
Eric Laurent4dc68062014-07-28 17:26:49 -07001415 index = inputDesc->mSessions.indexOf(session);
1416 if (index < 0) {
1417 ALOGW("stopInput() unknown session %d on input %d", session, input);
1418 return BAD_VALUE;
1419 }
1420
Eric Laurente552edb2014-03-10 17:42:56 -07001421 if (inputDesc->mRefCount == 0) {
1422 ALOGW("stopInput() input %d already stopped", input);
1423 return INVALID_OPERATION;
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001424 }
1425
1426 inputDesc->mRefCount--;
1427 if (inputDesc->mRefCount == 0) {
1428
Eric Laurente552edb2014-03-10 17:42:56 -07001429 // automatically disable the remote submix output when input is stopped
1430 if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1431 setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
Eric Laurent3b73df72014-03-11 09:06:29 -07001432 AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
Eric Laurente552edb2014-03-10 17:42:56 -07001433 }
1434
Eric Laurent1c333e22014-05-20 10:48:17 -07001435 resetInputDevice(input);
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07001436
1437 if (activeInputsCount() == 0) {
1438 SoundTrigger::setCaptureState(false);
1439 }
Eric Laurente552edb2014-03-10 17:42:56 -07001440 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001441 return NO_ERROR;
Eric Laurente552edb2014-03-10 17:42:56 -07001442}
1443
Eric Laurent4dc68062014-07-28 17:26:49 -07001444void AudioPolicyManager::releaseInput(audio_io_handle_t input,
1445 audio_session_t session)
Eric Laurente552edb2014-03-10 17:42:56 -07001446{
1447 ALOGV("releaseInput() %d", input);
1448 ssize_t index = mInputs.indexOfKey(input);
1449 if (index < 0) {
1450 ALOGW("releaseInput() releasing unknown input %d", input);
1451 return;
1452 }
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001453 sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1454 ALOG_ASSERT(inputDesc != 0);
Eric Laurent4dc68062014-07-28 17:26:49 -07001455
1456 index = inputDesc->mSessions.indexOf(session);
1457 if (index < 0) {
1458 ALOGW("releaseInput() unknown session %d on input %d", session, input);
1459 return;
1460 }
1461 inputDesc->mSessions.remove(session);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07001462 if (inputDesc->mOpenRefCount == 0) {
1463 ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
1464 return;
1465 }
1466 inputDesc->mOpenRefCount--;
1467 if (inputDesc->mOpenRefCount > 0) {
1468 ALOGV("releaseInput() exit > 0");
1469 return;
1470 }
1471
Eric Laurente552edb2014-03-10 17:42:56 -07001472 mpClientInterface->closeInput(input);
Eric Laurente552edb2014-03-10 17:42:56 -07001473 mInputs.removeItem(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07001474 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07001475 mpClientInterface->onAudioPortListUpdate();
Eric Laurente552edb2014-03-10 17:42:56 -07001476 ALOGV("releaseInput() exit");
1477}
1478
Eric Laurentd4692962014-05-05 18:13:44 -07001479void AudioPolicyManager::closeAllInputs() {
1480 for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
1481 mpClientInterface->closeInput(mInputs.keyAt(input_index));
1482 }
1483 mInputs.clear();
Eric Laurent6a94d692014-05-20 11:18:06 -07001484 nextAudioPortGeneration();
Eric Laurentd4692962014-05-05 18:13:44 -07001485}
1486
Eric Laurente0720872014-03-11 09:30:41 -07001487void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001488 int indexMin,
1489 int indexMax)
1490{
1491 ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1492 if (indexMin < 0 || indexMin >= indexMax) {
1493 ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
1494 return;
1495 }
1496 mStreams[stream].mIndexMin = indexMin;
1497 mStreams[stream].mIndexMax = indexMax;
1498}
1499
Eric Laurente0720872014-03-11 09:30:41 -07001500status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001501 int index,
1502 audio_devices_t device)
1503{
1504
1505 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1506 return BAD_VALUE;
1507 }
1508 if (!audio_is_output_device(device)) {
1509 return BAD_VALUE;
1510 }
1511
1512 // Force max volume if stream cannot be muted
1513 if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
1514
1515 ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
1516 stream, device, index);
1517
1518 // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
1519 // clear all device specific values
1520 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1521 mStreams[stream].mIndexCur.clear();
1522 }
1523 mStreams[stream].mIndexCur.add(device, index);
1524
1525 // compute and apply stream volume on all outputs according to connected device
1526 status_t status = NO_ERROR;
1527 for (size_t i = 0; i < mOutputs.size(); i++) {
1528 audio_devices_t curDevice =
1529 getDeviceForVolume(mOutputs.valueAt(i)->device());
1530 if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
1531 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
1532 if (volStatus != NO_ERROR) {
1533 status = volStatus;
1534 }
1535 }
1536 }
1537 return status;
1538}
1539
Eric Laurente0720872014-03-11 09:30:41 -07001540status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07001541 int *index,
1542 audio_devices_t device)
1543{
1544 if (index == NULL) {
1545 return BAD_VALUE;
1546 }
1547 if (!audio_is_output_device(device)) {
1548 return BAD_VALUE;
1549 }
1550 // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
1551 // the strategy the stream belongs to.
1552 if (device == AUDIO_DEVICE_OUT_DEFAULT) {
1553 device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
1554 }
1555 device = getDeviceForVolume(device);
1556
1557 *index = mStreams[stream].getVolumeIndex(device);
1558 ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
1559 return NO_ERROR;
1560}
1561
Eric Laurente0720872014-03-11 09:30:41 -07001562audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
Eric Laurente552edb2014-03-10 17:42:56 -07001563 const SortedVector<audio_io_handle_t>& outputs)
1564{
1565 // select one output among several suitable for global effects.
1566 // The priority is as follows:
1567 // 1: An offloaded output. If the effect ends up not being offloadable,
1568 // AudioFlinger will invalidate the track and the offloaded output
1569 // will be closed causing the effect to be moved to a PCM output.
1570 // 2: A deep buffer output
1571 // 3: the first output in the list
1572
1573 if (outputs.size() == 0) {
1574 return 0;
1575 }
1576
1577 audio_io_handle_t outputOffloaded = 0;
1578 audio_io_handle_t outputDeepBuffer = 0;
1579
1580 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001581 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
Eric Laurentd4692962014-05-05 18:13:44 -07001582 ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
Eric Laurente552edb2014-03-10 17:42:56 -07001583 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1584 outputOffloaded = outputs[i];
1585 }
1586 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1587 outputDeepBuffer = outputs[i];
1588 }
1589 }
1590
1591 ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
1592 outputOffloaded, outputDeepBuffer);
1593 if (outputOffloaded != 0) {
1594 return outputOffloaded;
1595 }
1596 if (outputDeepBuffer != 0) {
1597 return outputDeepBuffer;
1598 }
1599
1600 return outputs[0];
1601}
1602
Eric Laurente0720872014-03-11 09:30:41 -07001603audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
Eric Laurente552edb2014-03-10 17:42:56 -07001604{
1605 // apply simple rule where global effects are attached to the same output as MUSIC streams
1606
Eric Laurent3b73df72014-03-11 09:06:29 -07001607 routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
Eric Laurente552edb2014-03-10 17:42:56 -07001608 audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
1609 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
1610
1611 audio_io_handle_t output = selectOutputForEffects(dstOutputs);
1612 ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
1613 output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags);
1614
1615 return output;
1616}
1617
Eric Laurente0720872014-03-11 09:30:41 -07001618status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
Eric Laurente552edb2014-03-10 17:42:56 -07001619 audio_io_handle_t io,
1620 uint32_t strategy,
1621 int session,
1622 int id)
1623{
1624 ssize_t index = mOutputs.indexOfKey(io);
1625 if (index < 0) {
1626 index = mInputs.indexOfKey(io);
1627 if (index < 0) {
1628 ALOGW("registerEffect() unknown io %d", io);
1629 return INVALID_OPERATION;
1630 }
1631 }
1632
1633 if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
1634 ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
1635 desc->name, desc->memoryUsage);
1636 return INVALID_OPERATION;
1637 }
1638 mTotalEffectsMemory += desc->memoryUsage;
1639 ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
1640 desc->name, io, strategy, session, id);
1641 ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
1642
Eric Laurent1f2f2232014-06-02 12:01:23 -07001643 sp<EffectDescriptor> effectDesc = new EffectDescriptor();
1644 memcpy (&effectDesc->mDesc, desc, sizeof(effect_descriptor_t));
1645 effectDesc->mIo = io;
1646 effectDesc->mStrategy = (routing_strategy)strategy;
1647 effectDesc->mSession = session;
1648 effectDesc->mEnabled = false;
Eric Laurente552edb2014-03-10 17:42:56 -07001649
Eric Laurent1f2f2232014-06-02 12:01:23 -07001650 mEffects.add(id, effectDesc);
Eric Laurente552edb2014-03-10 17:42:56 -07001651
1652 return NO_ERROR;
1653}
1654
Eric Laurente0720872014-03-11 09:30:41 -07001655status_t AudioPolicyManager::unregisterEffect(int id)
Eric Laurente552edb2014-03-10 17:42:56 -07001656{
1657 ssize_t index = mEffects.indexOfKey(id);
1658 if (index < 0) {
1659 ALOGW("unregisterEffect() unknown effect ID %d", id);
1660 return INVALID_OPERATION;
1661 }
1662
Eric Laurent1f2f2232014-06-02 12:01:23 -07001663 sp<EffectDescriptor> effectDesc = mEffects.valueAt(index);
Eric Laurente552edb2014-03-10 17:42:56 -07001664
Eric Laurent1f2f2232014-06-02 12:01:23 -07001665 setEffectEnabled(effectDesc, false);
Eric Laurente552edb2014-03-10 17:42:56 -07001666
Eric Laurent1f2f2232014-06-02 12:01:23 -07001667 if (mTotalEffectsMemory < effectDesc->mDesc.memoryUsage) {
Eric Laurente552edb2014-03-10 17:42:56 -07001668 ALOGW("unregisterEffect() memory %d too big for total %d",
Eric Laurent1f2f2232014-06-02 12:01:23 -07001669 effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
1670 effectDesc->mDesc.memoryUsage = mTotalEffectsMemory;
Eric Laurente552edb2014-03-10 17:42:56 -07001671 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001672 mTotalEffectsMemory -= effectDesc->mDesc.memoryUsage;
Eric Laurente552edb2014-03-10 17:42:56 -07001673 ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
Eric Laurent1f2f2232014-06-02 12:01:23 -07001674 effectDesc->mDesc.name, id, effectDesc->mDesc.memoryUsage, mTotalEffectsMemory);
Eric Laurente552edb2014-03-10 17:42:56 -07001675
1676 mEffects.removeItem(id);
Eric Laurente552edb2014-03-10 17:42:56 -07001677
1678 return NO_ERROR;
1679}
1680
Eric Laurente0720872014-03-11 09:30:41 -07001681status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
Eric Laurente552edb2014-03-10 17:42:56 -07001682{
1683 ssize_t index = mEffects.indexOfKey(id);
1684 if (index < 0) {
1685 ALOGW("unregisterEffect() unknown effect ID %d", id);
1686 return INVALID_OPERATION;
1687 }
1688
1689 return setEffectEnabled(mEffects.valueAt(index), enabled);
1690}
1691
Eric Laurent1f2f2232014-06-02 12:01:23 -07001692status_t AudioPolicyManager::setEffectEnabled(const sp<EffectDescriptor>& effectDesc, bool enabled)
Eric Laurente552edb2014-03-10 17:42:56 -07001693{
Eric Laurent1f2f2232014-06-02 12:01:23 -07001694 if (enabled == effectDesc->mEnabled) {
Eric Laurente552edb2014-03-10 17:42:56 -07001695 ALOGV("setEffectEnabled(%s) effect already %s",
1696 enabled?"true":"false", enabled?"enabled":"disabled");
1697 return INVALID_OPERATION;
1698 }
1699
1700 if (enabled) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001701 if (mTotalEffectsCpuLoad + effectDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
Eric Laurente552edb2014-03-10 17:42:56 -07001702 ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
Eric Laurent1f2f2232014-06-02 12:01:23 -07001703 effectDesc->mDesc.name, (float)effectDesc->mDesc.cpuLoad/10);
Eric Laurente552edb2014-03-10 17:42:56 -07001704 return INVALID_OPERATION;
1705 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001706 mTotalEffectsCpuLoad += effectDesc->mDesc.cpuLoad;
Eric Laurente552edb2014-03-10 17:42:56 -07001707 ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
1708 } else {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001709 if (mTotalEffectsCpuLoad < effectDesc->mDesc.cpuLoad) {
Eric Laurente552edb2014-03-10 17:42:56 -07001710 ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
Eric Laurent1f2f2232014-06-02 12:01:23 -07001711 effectDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
1712 effectDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
Eric Laurente552edb2014-03-10 17:42:56 -07001713 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001714 mTotalEffectsCpuLoad -= effectDesc->mDesc.cpuLoad;
Eric Laurente552edb2014-03-10 17:42:56 -07001715 ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
1716 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07001717 effectDesc->mEnabled = enabled;
Eric Laurente552edb2014-03-10 17:42:56 -07001718 return NO_ERROR;
1719}
1720
Eric Laurente0720872014-03-11 09:30:41 -07001721bool AudioPolicyManager::isNonOffloadableEffectEnabled()
Eric Laurente552edb2014-03-10 17:42:56 -07001722{
1723 for (size_t i = 0; i < mEffects.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001724 sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
1725 if (effectDesc->mEnabled && (effectDesc->mStrategy == STRATEGY_MEDIA) &&
1726 ((effectDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
Eric Laurente552edb2014-03-10 17:42:56 -07001727 ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
Eric Laurent1f2f2232014-06-02 12:01:23 -07001728 effectDesc->mDesc.name, effectDesc->mSession);
Eric Laurente552edb2014-03-10 17:42:56 -07001729 return true;
1730 }
1731 }
1732 return false;
1733}
1734
Eric Laurente0720872014-03-11 09:30:41 -07001735bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
Eric Laurente552edb2014-03-10 17:42:56 -07001736{
1737 nsecs_t sysTime = systemTime();
1738 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001739 const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
Eric Laurent3b73df72014-03-11 09:06:29 -07001740 if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
Eric Laurente552edb2014-03-10 17:42:56 -07001741 return true;
1742 }
1743 }
1744 return false;
1745}
1746
Eric Laurente0720872014-03-11 09:30:41 -07001747bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07001748 uint32_t inPastMs) const
Eric Laurente552edb2014-03-10 17:42:56 -07001749{
1750 nsecs_t sysTime = systemTime();
1751 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001752 const sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001753 if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07001754 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
Eric Laurente552edb2014-03-10 17:42:56 -07001755 return true;
1756 }
1757 }
1758 return false;
1759}
1760
Eric Laurente0720872014-03-11 09:30:41 -07001761bool AudioPolicyManager::isSourceActive(audio_source_t source) const
Eric Laurente552edb2014-03-10 17:42:56 -07001762{
1763 for (size_t i = 0; i < mInputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07001764 const sp<AudioInputDescriptor> inputDescriptor = mInputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07001765 if ((inputDescriptor->mInputSource == (int)source ||
Eric Laurent3b73df72014-03-11 09:06:29 -07001766 (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
Eric Laurente552edb2014-03-10 17:42:56 -07001767 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
1768 && (inputDescriptor->mRefCount > 0)) {
1769 return true;
1770 }
1771 }
1772 return false;
1773}
1774
1775
Eric Laurente0720872014-03-11 09:30:41 -07001776status_t AudioPolicyManager::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07001777{
1778 const size_t SIZE = 256;
1779 char buffer[SIZE];
1780 String8 result;
1781
1782 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1783 result.append(buffer);
1784
1785 snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
1786 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07001787 snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
1788 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001789 snprintf(buffer, SIZE, " Force use for communications %d\n",
1790 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
Eric Laurente552edb2014-03-10 17:42:56 -07001791 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001792 snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]);
Eric Laurente552edb2014-03-10 17:42:56 -07001793 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001794 snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]);
Eric Laurente552edb2014-03-10 17:42:56 -07001795 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001796 snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]);
Eric Laurente552edb2014-03-10 17:42:56 -07001797 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07001798 snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]);
Eric Laurente552edb2014-03-10 17:42:56 -07001799 result.append(buffer);
Jungshik Jang7b24ee32014-07-15 19:38:42 +09001800 snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
1801 mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO]);
1802 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07001803
Eric Laurent3a4311c2014-03-17 12:00:47 -07001804 snprintf(buffer, SIZE, " Available output devices:\n");
1805 result.append(buffer);
1806 write(fd, result.string(), result.size());
Eric Laurent3a4311c2014-03-17 12:00:47 -07001807 for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07001808 mAvailableOutputDevices[i]->dump(fd, 2, i);
Eric Laurent3a4311c2014-03-17 12:00:47 -07001809 }
1810 snprintf(buffer, SIZE, "\n Available input devices:\n");
1811 write(fd, buffer, strlen(buffer));
Eric Laurent3a4311c2014-03-17 12:00:47 -07001812 for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07001813 mAvailableInputDevices[i]->dump(fd, 2, i);
Eric Laurent3a4311c2014-03-17 12:00:47 -07001814 }
Eric Laurente552edb2014-03-10 17:42:56 -07001815
1816 snprintf(buffer, SIZE, "\nHW Modules dump:\n");
1817 write(fd, buffer, strlen(buffer));
1818 for (size_t i = 0; i < mHwModules.size(); i++) {
Eric Laurentd4692962014-05-05 18:13:44 -07001819 snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07001820 write(fd, buffer, strlen(buffer));
1821 mHwModules[i]->dump(fd);
1822 }
1823
1824 snprintf(buffer, SIZE, "\nOutputs dump:\n");
1825 write(fd, buffer, strlen(buffer));
1826 for (size_t i = 0; i < mOutputs.size(); i++) {
1827 snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
1828 write(fd, buffer, strlen(buffer));
1829 mOutputs.valueAt(i)->dump(fd);
1830 }
1831
1832 snprintf(buffer, SIZE, "\nInputs dump:\n");
1833 write(fd, buffer, strlen(buffer));
1834 for (size_t i = 0; i < mInputs.size(); i++) {
1835 snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
1836 write(fd, buffer, strlen(buffer));
1837 mInputs.valueAt(i)->dump(fd);
1838 }
1839
1840 snprintf(buffer, SIZE, "\nStreams dump:\n");
1841 write(fd, buffer, strlen(buffer));
1842 snprintf(buffer, SIZE,
1843 " Stream Can be muted Index Min Index Max Index Cur [device : index]...\n");
1844 write(fd, buffer, strlen(buffer));
Mark Salyzynbeb9e302014-06-18 16:33:15 -07001845 for (size_t i = 0; i < AUDIO_STREAM_CNT; i++) {
Eric Laurentd4692962014-05-05 18:13:44 -07001846 snprintf(buffer, SIZE, " %02zu ", i);
Eric Laurente552edb2014-03-10 17:42:56 -07001847 write(fd, buffer, strlen(buffer));
1848 mStreams[i].dump(fd);
1849 }
1850
1851 snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
1852 (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
1853 write(fd, buffer, strlen(buffer));
1854
1855 snprintf(buffer, SIZE, "Registered effects:\n");
1856 write(fd, buffer, strlen(buffer));
1857 for (size_t i = 0; i < mEffects.size(); i++) {
1858 snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
1859 write(fd, buffer, strlen(buffer));
1860 mEffects.valueAt(i)->dump(fd);
1861 }
1862
Eric Laurent4d416952014-08-10 14:07:09 -07001863 snprintf(buffer, SIZE, "\nAudio Patches:\n");
1864 write(fd, buffer, strlen(buffer));
1865 for (size_t i = 0; i < mAudioPatches.size(); i++) {
1866 mAudioPatches[i]->dump(fd, 2, i);
1867 }
Eric Laurente552edb2014-03-10 17:42:56 -07001868
1869 return NO_ERROR;
1870}
1871
1872// This function checks for the parameters which can be offloaded.
1873// This can be enhanced depending on the capability of the DSP and policy
1874// of the system.
Eric Laurente0720872014-03-11 09:30:41 -07001875bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
Eric Laurente552edb2014-03-10 17:42:56 -07001876{
1877 ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
Eric Laurentd4692962014-05-05 18:13:44 -07001878 " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
Eric Laurente552edb2014-03-10 17:42:56 -07001879 offloadInfo.sample_rate, offloadInfo.channel_mask,
1880 offloadInfo.format,
1881 offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
1882 offloadInfo.has_video);
1883
1884 // Check if offload has been disabled
1885 char propValue[PROPERTY_VALUE_MAX];
1886 if (property_get("audio.offload.disable", propValue, "0")) {
1887 if (atoi(propValue) != 0) {
1888 ALOGV("offload disabled by audio.offload.disable=%s", propValue );
1889 return false;
1890 }
1891 }
1892
1893 // Check if stream type is music, then only allow offload as of now.
1894 if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
1895 {
1896 ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
1897 return false;
1898 }
1899
1900 //TODO: enable audio offloading with video when ready
1901 if (offloadInfo.has_video)
1902 {
1903 ALOGV("isOffloadSupported: has_video == true, returning false");
1904 return false;
1905 }
1906
1907 //If duration is less than minimum value defined in property, return false
1908 if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
1909 if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
1910 ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
1911 return false;
1912 }
1913 } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
1914 ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
1915 return false;
1916 }
1917
1918 // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1919 // creating an offloaded track and tearing it down immediately after start when audioflinger
1920 // detects there is an active non offloadable effect.
1921 // FIXME: We should check the audio session here but we do not have it in this context.
1922 // This may prevent offloading in rare situations where effects are left active by apps
1923 // in the background.
1924 if (isNonOffloadableEffectEnabled()) {
1925 return false;
1926 }
1927
1928 // See if there is a profile to support this.
1929 // AUDIO_DEVICE_NONE
Eric Laurent1c333e22014-05-20 10:48:17 -07001930 sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
Eric Laurente552edb2014-03-10 17:42:56 -07001931 offloadInfo.sample_rate,
1932 offloadInfo.format,
1933 offloadInfo.channel_mask,
1934 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
Eric Laurent1c333e22014-05-20 10:48:17 -07001935 ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
1936 return (profile != 0);
Eric Laurente552edb2014-03-10 17:42:56 -07001937}
1938
Eric Laurent6a94d692014-05-20 11:18:06 -07001939status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
1940 audio_port_type_t type,
1941 unsigned int *num_ports,
1942 struct audio_port *ports,
1943 unsigned int *generation)
1944{
1945 if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
1946 generation == NULL) {
1947 return BAD_VALUE;
1948 }
1949 ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
1950 if (ports == NULL) {
1951 *num_ports = 0;
1952 }
1953
1954 size_t portsWritten = 0;
1955 size_t portsMax = *num_ports;
1956 *num_ports = 0;
1957 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
1958 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
1959 for (size_t i = 0;
1960 i < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
1961 mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
1962 }
1963 *num_ports += mAvailableOutputDevices.size();
1964 }
1965 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
1966 for (size_t i = 0;
1967 i < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
1968 mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
1969 }
1970 *num_ports += mAvailableInputDevices.size();
1971 }
1972 }
1973 if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
1974 if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
1975 for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
1976 mInputs[i]->toAudioPort(&ports[portsWritten++]);
1977 }
1978 *num_ports += mInputs.size();
1979 }
1980 if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
Eric Laurent84c70242014-06-23 08:46:27 -07001981 size_t numOutputs = 0;
1982 for (size_t i = 0; i < mOutputs.size(); i++) {
1983 if (!mOutputs[i]->isDuplicated()) {
1984 numOutputs++;
1985 if (portsWritten < portsMax) {
1986 mOutputs[i]->toAudioPort(&ports[portsWritten++]);
1987 }
1988 }
Eric Laurent6a94d692014-05-20 11:18:06 -07001989 }
Eric Laurent84c70242014-06-23 08:46:27 -07001990 *num_ports += numOutputs;
Eric Laurent6a94d692014-05-20 11:18:06 -07001991 }
1992 }
1993 *generation = curAudioPortGeneration();
Mark Salyzynbeb9e302014-06-18 16:33:15 -07001994 ALOGV("listAudioPorts() got %zu ports needed %d", portsWritten, *num_ports);
Eric Laurent6a94d692014-05-20 11:18:06 -07001995 return NO_ERROR;
1996}
1997
1998status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
1999{
2000 return NO_ERROR;
2001}
2002
Eric Laurent1f2f2232014-06-02 12:01:23 -07002003sp<AudioPolicyManager::AudioOutputDescriptor> AudioPolicyManager::getOutputFromId(
Eric Laurent6a94d692014-05-20 11:18:06 -07002004 audio_port_handle_t id) const
2005{
Eric Laurent1f2f2232014-06-02 12:01:23 -07002006 sp<AudioOutputDescriptor> outputDesc = NULL;
Eric Laurent6a94d692014-05-20 11:18:06 -07002007 for (size_t i = 0; i < mOutputs.size(); i++) {
2008 outputDesc = mOutputs.valueAt(i);
2009 if (outputDesc->mId == id) {
2010 break;
2011 }
2012 }
2013 return outputDesc;
2014}
2015
Eric Laurent1f2f2232014-06-02 12:01:23 -07002016sp<AudioPolicyManager::AudioInputDescriptor> AudioPolicyManager::getInputFromId(
Eric Laurent6a94d692014-05-20 11:18:06 -07002017 audio_port_handle_t id) const
2018{
Eric Laurent1f2f2232014-06-02 12:01:23 -07002019 sp<AudioInputDescriptor> inputDesc = NULL;
Eric Laurent6a94d692014-05-20 11:18:06 -07002020 for (size_t i = 0; i < mInputs.size(); i++) {
2021 inputDesc = mInputs.valueAt(i);
2022 if (inputDesc->mId == id) {
2023 break;
2024 }
2025 }
2026 return inputDesc;
2027}
2028
Eric Laurent1f2f2232014-06-02 12:01:23 -07002029sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleForDevice(
2030 audio_devices_t device) const
Eric Laurent6a94d692014-05-20 11:18:06 -07002031{
Eric Laurent1f2f2232014-06-02 12:01:23 -07002032 sp <HwModule> module;
2033
Eric Laurent6a94d692014-05-20 11:18:06 -07002034 for (size_t i = 0; i < mHwModules.size(); i++) {
2035 if (mHwModules[i]->mHandle == 0) {
2036 continue;
2037 }
2038 if (audio_is_output_device(device)) {
2039 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2040 {
2041 if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
2042 return mHwModules[i];
2043 }
2044 }
2045 } else {
2046 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) {
2047 if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() &
2048 device & ~AUDIO_DEVICE_BIT_IN) {
2049 return mHwModules[i];
2050 }
2051 }
2052 }
2053 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07002054 return module;
Eric Laurent6a94d692014-05-20 11:18:06 -07002055}
2056
Eric Laurent1f2f2232014-06-02 12:01:23 -07002057sp <AudioPolicyManager::HwModule> AudioPolicyManager::getModuleFromName(const char *name) const
Eric Laurent1afeecb2014-05-14 08:52:28 -07002058{
Eric Laurent1f2f2232014-06-02 12:01:23 -07002059 sp <HwModule> module;
2060
Eric Laurent1afeecb2014-05-14 08:52:28 -07002061 for (size_t i = 0; i < mHwModules.size(); i++)
2062 {
2063 if (strcmp(mHwModules[i]->mName, name) == 0) {
2064 return mHwModules[i];
2065 }
2066 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07002067 return module;
Eric Laurent1afeecb2014-05-14 08:52:28 -07002068}
2069
Eric Laurentc2730ba2014-07-20 15:47:07 -07002070audio_devices_t AudioPolicyManager::availablePrimaryOutputDevices()
2071{
2072 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
2073 audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
2074 return devices & mAvailableOutputDevices.types();
2075}
2076
2077audio_devices_t AudioPolicyManager::availablePrimaryInputDevices()
2078{
2079 audio_module_handle_t primaryHandle =
2080 mOutputs.valueFor(mPrimaryOutput)->mProfile->mModule->mHandle;
2081 audio_devices_t devices = AUDIO_DEVICE_NONE;
2082 for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
2083 if (mAvailableInputDevices[i]->mModule->mHandle == primaryHandle) {
2084 devices |= mAvailableInputDevices[i]->mDeviceType;
2085 }
2086 }
2087 return devices;
2088}
Eric Laurent1afeecb2014-05-14 08:52:28 -07002089
Eric Laurent6a94d692014-05-20 11:18:06 -07002090status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
2091 audio_patch_handle_t *handle,
2092 uid_t uid)
2093{
2094 ALOGV("createAudioPatch()");
2095
2096 if (handle == NULL || patch == NULL) {
2097 return BAD_VALUE;
2098 }
2099 ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
2100
Eric Laurent874c42872014-08-08 15:13:39 -07002101 if (patch->num_sources == 0 || patch->num_sources > AUDIO_PATCH_PORTS_MAX ||
2102 patch->num_sinks == 0 || patch->num_sinks > AUDIO_PATCH_PORTS_MAX) {
2103 return BAD_VALUE;
2104 }
2105 // only one source per audio patch supported for now
2106 if (patch->num_sources > 1) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002107 return INVALID_OPERATION;
2108 }
Eric Laurent874c42872014-08-08 15:13:39 -07002109
2110 if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002111 return INVALID_OPERATION;
2112 }
Eric Laurent874c42872014-08-08 15:13:39 -07002113 for (size_t i = 0; i < patch->num_sinks; i++) {
2114 if (patch->sinks[i].role != AUDIO_PORT_ROLE_SINK) {
2115 return INVALID_OPERATION;
2116 }
2117 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002118
2119 sp<AudioPatch> patchDesc;
2120 ssize_t index = mAudioPatches.indexOfKey(*handle);
2121
Eric Laurent6a94d692014-05-20 11:18:06 -07002122 ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
2123 patch->sources[0].role,
2124 patch->sources[0].type);
Eric Laurent874c42872014-08-08 15:13:39 -07002125#if LOG_NDEBUG == 0
2126 for (size_t i = 0; i < patch->num_sinks; i++) {
2127 ALOGV("createAudioPatch sink %d: id %d role %d type %d", i, patch->sinks[i].id,
2128 patch->sinks[i].role,
2129 patch->sinks[i].type);
2130 }
2131#endif
Eric Laurent6a94d692014-05-20 11:18:06 -07002132
2133 if (index >= 0) {
2134 patchDesc = mAudioPatches.valueAt(index);
2135 ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2136 mUidCached, patchDesc->mUid, uid);
2137 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2138 return INVALID_OPERATION;
2139 }
2140 } else {
2141 *handle = 0;
2142 }
2143
2144 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002145 sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002146 if (outputDesc == NULL) {
2147 ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
2148 return BAD_VALUE;
2149 }
Eric Laurent84c70242014-06-23 08:46:27 -07002150 ALOG_ASSERT(!outputDesc->isDuplicated(),"duplicated output %d in source in ports",
2151 outputDesc->mIoHandle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002152 if (patchDesc != 0) {
2153 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
2154 ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
2155 patchDesc->mPatch.sources[0].id, patch->sources[0].id);
2156 return BAD_VALUE;
2157 }
2158 }
Eric Laurent874c42872014-08-08 15:13:39 -07002159 DeviceVector devices;
2160 for (size_t i = 0; i < patch->num_sinks; i++) {
2161 // Only support mix to devices connection
2162 // TODO add support for mix to mix connection
2163 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2164 ALOGV("createAudioPatch() source mix but sink is not a device");
2165 return INVALID_OPERATION;
2166 }
2167 sp<DeviceDescriptor> devDesc =
2168 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2169 if (devDesc == 0) {
2170 ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[i].id);
2171 return BAD_VALUE;
2172 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002173
Eric Laurent874c42872014-08-08 15:13:39 -07002174 if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType,
2175 patch->sources[0].sample_rate,
2176 NULL, // updatedSamplingRate
2177 patch->sources[0].format,
2178 patch->sources[0].channel_mask,
2179 AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) {
2180 ALOGV("createAudioPatch() profile not supported for device %08x",
2181 devDesc->mDeviceType);
2182 return INVALID_OPERATION;
2183 }
2184 devices.add(devDesc);
2185 }
2186 if (devices.size() == 0) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002187 return INVALID_OPERATION;
2188 }
Eric Laurent874c42872014-08-08 15:13:39 -07002189
Eric Laurent6a94d692014-05-20 11:18:06 -07002190 // TODO: reconfigure output format and channels here
2191 ALOGV("createAudioPatch() setting device %08x on output %d",
Eric Laurent874c42872014-08-08 15:13:39 -07002192 devices.types(), outputDesc->mIoHandle);
2193 setOutputDevice(outputDesc->mIoHandle, devices.types(), true, 0, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002194 index = mAudioPatches.indexOfKey(*handle);
2195 if (index >= 0) {
2196 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2197 ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
2198 }
2199 patchDesc = mAudioPatches.valueAt(index);
2200 patchDesc->mUid = uid;
2201 ALOGV("createAudioPatch() success");
2202 } else {
2203 ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
2204 return INVALID_OPERATION;
2205 }
2206 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2207 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
2208 // input device to input mix connection
Eric Laurent874c42872014-08-08 15:13:39 -07002209 // only one sink supported when connecting an input device to a mix
2210 if (patch->num_sinks > 1) {
2211 return INVALID_OPERATION;
2212 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07002213 sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002214 if (inputDesc == NULL) {
2215 return BAD_VALUE;
2216 }
2217 if (patchDesc != 0) {
2218 if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
2219 return BAD_VALUE;
2220 }
2221 }
2222 sp<DeviceDescriptor> devDesc =
2223 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
2224 if (devDesc == 0) {
2225 return BAD_VALUE;
2226 }
2227
Eric Laurent84c70242014-06-23 08:46:27 -07002228 if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType,
Glenn Kastencbd48022014-07-24 13:46:44 -07002229 patch->sinks[0].sample_rate,
2230 NULL, /*updatedSampleRate*/
Eric Laurent6a94d692014-05-20 11:18:06 -07002231 patch->sinks[0].format,
2232 patch->sinks[0].channel_mask,
Glenn Kasten6a8ab052014-07-24 14:08:35 -07002233 // FIXME for the parameter type,
2234 // and the NONE
2235 (audio_output_flags_t)
2236 AUDIO_INPUT_FLAG_NONE)) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002237 return INVALID_OPERATION;
2238 }
2239 // TODO: reconfigure output format and channels here
2240 ALOGV("createAudioPatch() setting device %08x on output %d",
Eric Laurent84c70242014-06-23 08:46:27 -07002241 devDesc->mDeviceType, inputDesc->mIoHandle);
Eric Laurent874c42872014-08-08 15:13:39 -07002242 setInputDevice(inputDesc->mIoHandle, devDesc->mDeviceType, true, handle);
Eric Laurent6a94d692014-05-20 11:18:06 -07002243 index = mAudioPatches.indexOfKey(*handle);
2244 if (index >= 0) {
2245 if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
2246 ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
2247 }
2248 patchDesc = mAudioPatches.valueAt(index);
2249 patchDesc->mUid = uid;
2250 ALOGV("createAudioPatch() success");
2251 } else {
2252 ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
2253 return INVALID_OPERATION;
2254 }
2255 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2256 // device to device connection
2257 if (patchDesc != 0) {
Eric Laurent874c42872014-08-08 15:13:39 -07002258 if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
Eric Laurent6a94d692014-05-20 11:18:06 -07002259 return BAD_VALUE;
2260 }
2261 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002262 sp<DeviceDescriptor> srcDeviceDesc =
2263 mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
Eric Laurent874c42872014-08-08 15:13:39 -07002264
Eric Laurent6a94d692014-05-20 11:18:06 -07002265 //update source and sink with our own data as the data passed in the patch may
2266 // be incomplete.
2267 struct audio_patch newPatch = *patch;
2268 srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
Eric Laurent874c42872014-08-08 15:13:39 -07002269 if (srcDeviceDesc == 0) {
2270 return BAD_VALUE;
2271 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002272
Eric Laurent874c42872014-08-08 15:13:39 -07002273 for (size_t i = 0; i < patch->num_sinks; i++) {
2274 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
2275 ALOGV("createAudioPatch() source device but one sink is not a device");
2276 return INVALID_OPERATION;
2277 }
2278
2279 sp<DeviceDescriptor> sinkDeviceDesc =
2280 mAvailableOutputDevices.getDeviceFromId(patch->sinks[i].id);
2281 if (sinkDeviceDesc == 0) {
2282 return BAD_VALUE;
2283 }
2284 sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[i], &patch->sinks[i]);
2285
2286 if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) {
2287 // only one sink supported when connected devices across HW modules
2288 if (patch->num_sinks > 1) {
Eric Laurent83b88082014-06-20 18:31:16 -07002289 return INVALID_OPERATION;
2290 }
Eric Laurent874c42872014-08-08 15:13:39 -07002291 SortedVector<audio_io_handle_t> outputs =
2292 getOutputsForDevice(sinkDeviceDesc->mDeviceType,
2293 mOutputs);
2294 // if the sink device is reachable via an opened output stream, request to go via
2295 // this output stream by adding a second source to the patch description
2296 audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE);
2297 if (output != AUDIO_IO_HANDLE_NONE) {
2298 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
2299 if (outputDesc->isDuplicated()) {
2300 return INVALID_OPERATION;
2301 }
2302 outputDesc->toAudioPortConfig(&newPatch.sources[1], &patch->sources[0]);
2303 newPatch.num_sources = 2;
2304 }
Eric Laurent83b88082014-06-20 18:31:16 -07002305 }
Eric Laurent6a94d692014-05-20 11:18:06 -07002306 }
2307 // TODO: check from routing capabilities in config file and other conflicting patches
2308
2309 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
2310 if (index >= 0) {
2311 afPatchHandle = patchDesc->mAfPatchHandle;
2312 }
2313
2314 status_t status = mpClientInterface->createAudioPatch(&newPatch,
2315 &afPatchHandle,
2316 0);
2317 ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
2318 status, afPatchHandle);
2319 if (status == NO_ERROR) {
2320 if (index < 0) {
2321 patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
2322 &newPatch, uid);
2323 addAudioPatch(patchDesc->mHandle, patchDesc);
2324 } else {
2325 patchDesc->mPatch = newPatch;
2326 }
2327 patchDesc->mAfPatchHandle = afPatchHandle;
2328 *handle = patchDesc->mHandle;
2329 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002330 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002331 } else {
2332 ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
2333 status);
2334 return INVALID_OPERATION;
2335 }
2336 } else {
2337 return BAD_VALUE;
2338 }
2339 } else {
2340 return BAD_VALUE;
2341 }
2342 return NO_ERROR;
2343}
2344
2345status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
2346 uid_t uid)
2347{
2348 ALOGV("releaseAudioPatch() patch %d", handle);
2349
2350 ssize_t index = mAudioPatches.indexOfKey(handle);
2351
2352 if (index < 0) {
2353 return BAD_VALUE;
2354 }
2355 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
2356 ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
2357 mUidCached, patchDesc->mUid, uid);
2358 if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
2359 return INVALID_OPERATION;
2360 }
2361
2362 struct audio_patch *patch = &patchDesc->mPatch;
2363 patchDesc->mUid = mUidCached;
2364 if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002365 sp<AudioOutputDescriptor> outputDesc = getOutputFromId(patch->sources[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002366 if (outputDesc == NULL) {
2367 ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
2368 return BAD_VALUE;
2369 }
2370
2371 setOutputDevice(outputDesc->mIoHandle,
2372 getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/),
2373 true,
2374 0,
2375 NULL);
2376 } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
2377 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002378 sp<AudioInputDescriptor> inputDesc = getInputFromId(patch->sinks[0].id);
Eric Laurent6a94d692014-05-20 11:18:06 -07002379 if (inputDesc == NULL) {
2380 ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
2381 return BAD_VALUE;
2382 }
2383 setInputDevice(inputDesc->mIoHandle,
2384 getNewInputDevice(inputDesc->mIoHandle),
2385 true,
2386 NULL);
2387 } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
2388 audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle;
2389 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
2390 ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
2391 status, patchDesc->mAfPatchHandle);
2392 removeAudioPatch(patchDesc->mHandle);
2393 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07002394 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent6a94d692014-05-20 11:18:06 -07002395 } else {
2396 return BAD_VALUE;
2397 }
2398 } else {
2399 return BAD_VALUE;
2400 }
2401 return NO_ERROR;
2402}
2403
2404status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
2405 struct audio_patch *patches,
2406 unsigned int *generation)
2407{
2408 if (num_patches == NULL || (*num_patches != 0 && patches == NULL) ||
2409 generation == NULL) {
2410 return BAD_VALUE;
2411 }
Mark Salyzynbeb9e302014-06-18 16:33:15 -07002412 ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu",
Eric Laurent6a94d692014-05-20 11:18:06 -07002413 *num_patches, patches, mAudioPatches.size());
2414 if (patches == NULL) {
2415 *num_patches = 0;
2416 }
2417
2418 size_t patchesWritten = 0;
2419 size_t patchesMax = *num_patches;
2420 for (size_t i = 0;
2421 i < mAudioPatches.size() && patchesWritten < patchesMax; i++) {
2422 patches[patchesWritten] = mAudioPatches[i]->mPatch;
2423 patches[patchesWritten++].id = mAudioPatches[i]->mHandle;
Mark Salyzynbeb9e302014-06-18 16:33:15 -07002424 ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07002425 i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks);
2426 }
2427 *num_patches = mAudioPatches.size();
2428
2429 *generation = curAudioPortGeneration();
Mark Salyzynbeb9e302014-06-18 16:33:15 -07002430 ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches);
Eric Laurent6a94d692014-05-20 11:18:06 -07002431 return NO_ERROR;
2432}
2433
Eric Laurente1715a42014-05-20 11:30:42 -07002434status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
Eric Laurent6a94d692014-05-20 11:18:06 -07002435{
Eric Laurente1715a42014-05-20 11:30:42 -07002436 ALOGV("setAudioPortConfig()");
2437
2438 if (config == NULL) {
2439 return BAD_VALUE;
2440 }
2441 ALOGV("setAudioPortConfig() on port handle %d", config->id);
2442 // Only support gain configuration for now
Eric Laurenta121f902014-06-03 13:32:54 -07002443 if (config->config_mask != AUDIO_PORT_CONFIG_GAIN) {
2444 return INVALID_OPERATION;
Eric Laurente1715a42014-05-20 11:30:42 -07002445 }
2446
Eric Laurenta121f902014-06-03 13:32:54 -07002447 sp<AudioPortConfig> audioPortConfig;
Eric Laurente1715a42014-05-20 11:30:42 -07002448 if (config->type == AUDIO_PORT_TYPE_MIX) {
2449 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002450 sp<AudioOutputDescriptor> outputDesc = getOutputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002451 if (outputDesc == NULL) {
2452 return BAD_VALUE;
2453 }
Eric Laurent84c70242014-06-23 08:46:27 -07002454 ALOG_ASSERT(!outputDesc->isDuplicated(),
2455 "setAudioPortConfig() called on duplicated output %d",
2456 outputDesc->mIoHandle);
Eric Laurenta121f902014-06-03 13:32:54 -07002457 audioPortConfig = outputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002458 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002459 sp<AudioInputDescriptor> inputDesc = getInputFromId(config->id);
Eric Laurente1715a42014-05-20 11:30:42 -07002460 if (inputDesc == NULL) {
2461 return BAD_VALUE;
2462 }
Eric Laurenta121f902014-06-03 13:32:54 -07002463 audioPortConfig = inputDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002464 } else {
2465 return BAD_VALUE;
2466 }
2467 } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
2468 sp<DeviceDescriptor> deviceDesc;
2469 if (config->role == AUDIO_PORT_ROLE_SOURCE) {
2470 deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
2471 } else if (config->role == AUDIO_PORT_ROLE_SINK) {
2472 deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
2473 } else {
2474 return BAD_VALUE;
2475 }
2476 if (deviceDesc == NULL) {
2477 return BAD_VALUE;
2478 }
Eric Laurenta121f902014-06-03 13:32:54 -07002479 audioPortConfig = deviceDesc;
Eric Laurente1715a42014-05-20 11:30:42 -07002480 } else {
2481 return BAD_VALUE;
2482 }
2483
Eric Laurenta121f902014-06-03 13:32:54 -07002484 struct audio_port_config backupConfig;
2485 status_t status = audioPortConfig->applyAudioPortConfig(config, &backupConfig);
2486 if (status == NO_ERROR) {
2487 struct audio_port_config newConfig;
2488 audioPortConfig->toAudioPortConfig(&newConfig, config);
2489 status = mpClientInterface->setAudioPortConfig(&newConfig, 0);
Eric Laurente1715a42014-05-20 11:30:42 -07002490 }
Eric Laurenta121f902014-06-03 13:32:54 -07002491 if (status != NO_ERROR) {
2492 audioPortConfig->applyAudioPortConfig(&backupConfig);
Eric Laurente1715a42014-05-20 11:30:42 -07002493 }
Eric Laurente1715a42014-05-20 11:30:42 -07002494
2495 return status;
Eric Laurent6a94d692014-05-20 11:18:06 -07002496}
2497
2498void AudioPolicyManager::clearAudioPatches(uid_t uid)
2499{
2500 for (ssize_t i = 0; i < (ssize_t)mAudioPatches.size(); i++) {
2501 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
2502 if (patchDesc->mUid == uid) {
2503 // releaseAudioPatch() removes the patch from mAudioPatches
2504 if (releaseAudioPatch(mAudioPatches.keyAt(i), uid) == NO_ERROR) {
2505 i--;
2506 }
2507 }
2508 }
2509}
2510
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07002511status_t AudioPolicyManager::acquireSoundTriggerSession(audio_session_t *session,
2512 audio_io_handle_t *ioHandle,
2513 audio_devices_t *device)
2514{
2515 *session = (audio_session_t)mpClientInterface->newAudioUniqueId();
2516 *ioHandle = (audio_io_handle_t)mpClientInterface->newAudioUniqueId();
2517 *device = getDeviceForInputSource(AUDIO_SOURCE_HOTWORD);
2518
2519 mSoundTriggerSessions.add(*session, *ioHandle);
2520
2521 return NO_ERROR;
2522}
2523
2524status_t AudioPolicyManager::releaseSoundTriggerSession(audio_session_t session)
2525{
2526 ssize_t index = mSoundTriggerSessions.indexOfKey(session);
2527 if (index < 0) {
2528 ALOGW("acquireSoundTriggerSession() session %d not registered", session);
2529 return BAD_VALUE;
2530 }
2531
2532 mSoundTriggerSessions.removeItem(session);
2533 return NO_ERROR;
2534}
2535
Eric Laurent6a94d692014-05-20 11:18:06 -07002536status_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle,
2537 const sp<AudioPatch>& patch)
2538{
2539 ssize_t index = mAudioPatches.indexOfKey(handle);
2540
2541 if (index >= 0) {
2542 ALOGW("addAudioPatch() patch %d already in", handle);
2543 return ALREADY_EXISTS;
2544 }
2545 mAudioPatches.add(handle, patch);
2546 ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d"
2547 "sink handle %d",
2548 handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks,
2549 patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id);
2550 return NO_ERROR;
2551}
2552
2553status_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle)
2554{
2555 ssize_t index = mAudioPatches.indexOfKey(handle);
2556
2557 if (index < 0) {
2558 ALOGW("removeAudioPatch() patch %d not in", handle);
2559 return ALREADY_EXISTS;
2560 }
2561 ALOGV("removeAudioPatch() handle %d af handle %d", handle,
2562 mAudioPatches.valueAt(index)->mAfPatchHandle);
2563 mAudioPatches.removeItemsAt(index);
2564 return NO_ERROR;
2565}
2566
Eric Laurente552edb2014-03-10 17:42:56 -07002567// ----------------------------------------------------------------------------
Eric Laurente0720872014-03-11 09:30:41 -07002568// AudioPolicyManager
Eric Laurente552edb2014-03-10 17:42:56 -07002569// ----------------------------------------------------------------------------
2570
Eric Laurent3a4311c2014-03-17 12:00:47 -07002571uint32_t AudioPolicyManager::nextUniqueId()
2572{
2573 return android_atomic_inc(&mNextUniqueId);
2574}
2575
Eric Laurent6a94d692014-05-20 11:18:06 -07002576uint32_t AudioPolicyManager::nextAudioPortGeneration()
2577{
2578 return android_atomic_inc(&mAudioPortGeneration);
2579}
2580
Eric Laurente0720872014-03-11 09:30:41 -07002581AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
Eric Laurente552edb2014-03-10 17:42:56 -07002582 :
2583#ifdef AUDIO_POLICY_TEST
2584 Thread(false),
2585#endif //AUDIO_POLICY_TEST
2586 mPrimaryOutput((audio_io_handle_t)0),
Eric Laurent3b73df72014-03-11 09:06:29 -07002587 mPhoneState(AUDIO_MODE_NORMAL),
Eric Laurente552edb2014-03-10 17:42:56 -07002588 mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
2589 mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
Eric Laurent3a4311c2014-03-17 12:00:47 -07002590 mA2dpSuspended(false),
Eric Laurent6a94d692014-05-20 11:18:06 -07002591 mSpeakerDrcEnabled(false), mNextUniqueId(1),
2592 mAudioPortGeneration(1)
Eric Laurente552edb2014-03-10 17:42:56 -07002593{
Eric Laurent6a94d692014-05-20 11:18:06 -07002594 mUidCached = getuid();
Eric Laurente552edb2014-03-10 17:42:56 -07002595 mpClientInterface = clientInterface;
2596
Eric Laurent3b73df72014-03-11 09:06:29 -07002597 for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
2598 mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07002599 }
2600
Eric Laurent1afeecb2014-05-14 08:52:28 -07002601 mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER);
Eric Laurente552edb2014-03-10 17:42:56 -07002602 if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
2603 if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
2604 ALOGE("could not load audio policy configuration file, setting defaults");
2605 defaultAudioPolicyConfig();
2606 }
2607 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002608 // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
Eric Laurente552edb2014-03-10 17:42:56 -07002609
2610 // must be done after reading the policy
2611 initializeVolumeCurves();
2612
2613 // open all output streams needed to access attached devices
Eric Laurent3a4311c2014-03-17 12:00:47 -07002614 audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
2615 audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
Eric Laurente552edb2014-03-10 17:42:56 -07002616 for (size_t i = 0; i < mHwModules.size(); i++) {
2617 mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
2618 if (mHwModules[i]->mHandle == 0) {
2619 ALOGW("could not open HW module %s", mHwModules[i]->mName);
2620 continue;
2621 }
2622 // open all output streams needed to access attached devices
2623 // except for direct output streams that are only opened when they are actually
2624 // required by an app.
Eric Laurent3a4311c2014-03-17 12:00:47 -07002625 // This also validates mAvailableOutputDevices list
Eric Laurente552edb2014-03-10 17:42:56 -07002626 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
2627 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002628 const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002629
Eric Laurent3a4311c2014-03-17 12:00:47 -07002630 if (outProfile->mSupportedDevices.isEmpty()) {
2631 ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
2632 continue;
2633 }
2634
Eric Laurent83b88082014-06-20 18:31:16 -07002635 audio_devices_t profileType = outProfile->mSupportedDevices.types();
2636 if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) {
2637 profileType = mDefaultOutputDevice->mDeviceType;
2638 } else {
2639 profileType = outProfile->mSupportedDevices[0]->mDeviceType;
2640 }
2641 if ((profileType & outputDeviceTypes) &&
Eric Laurente552edb2014-03-10 17:42:56 -07002642 ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002643 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002644
Eric Laurent83b88082014-06-20 18:31:16 -07002645 outputDesc->mDevice = profileType;
Eric Laurentcf2c0212014-07-25 16:20:43 -07002646 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2647 config.sample_rate = outputDesc->mSamplingRate;
2648 config.channel_mask = outputDesc->mChannelMask;
2649 config.format = outputDesc->mFormat;
2650 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
2651 status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
2652 &output,
2653 &config,
2654 &outputDesc->mDevice,
2655 String8(""),
2656 &outputDesc->mLatency,
2657 outputDesc->mFlags);
2658
2659 if (status != NO_ERROR) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07002660 ALOGW("Cannot open output stream for device %08x on hw module %s",
2661 outputDesc->mDevice,
2662 mHwModules[i]->mName);
Eric Laurente552edb2014-03-10 17:42:56 -07002663 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07002664 outputDesc->mSamplingRate = config.sample_rate;
2665 outputDesc->mChannelMask = config.channel_mask;
2666 outputDesc->mFormat = config.format;
2667
Eric Laurent5b61ddd2014-05-07 09:10:01 -07002668 for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002669 audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002670 ssize_t index =
Eric Laurent5b61ddd2014-05-07 09:10:01 -07002671 mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002672 // give a valid ID to an attached device once confirmed it is reachable
2673 if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) {
2674 mAvailableOutputDevices[index]->mId = nextUniqueId();
Eric Laurent6a94d692014-05-20 11:18:06 -07002675 mAvailableOutputDevices[index]->mModule = mHwModules[i];
Eric Laurent3a4311c2014-03-17 12:00:47 -07002676 }
2677 }
Eric Laurente552edb2014-03-10 17:42:56 -07002678 if (mPrimaryOutput == 0 &&
2679 outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
2680 mPrimaryOutput = output;
2681 }
2682 addOutput(output, outputDesc);
2683 setOutputDevice(output,
Eric Laurent3a4311c2014-03-17 12:00:47 -07002684 outputDesc->mDevice,
Eric Laurente552edb2014-03-10 17:42:56 -07002685 true);
2686 }
2687 }
2688 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002689 // open input streams needed to access attached devices to validate
2690 // mAvailableInputDevices list
2691 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
2692 {
Eric Laurent1c333e22014-05-20 10:48:17 -07002693 const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
Eric Laurente552edb2014-03-10 17:42:56 -07002694
Eric Laurent3a4311c2014-03-17 12:00:47 -07002695 if (inProfile->mSupportedDevices.isEmpty()) {
2696 ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
2697 continue;
2698 }
2699
Eric Laurent83b88082014-06-20 18:31:16 -07002700 audio_devices_t profileType = inProfile->mSupportedDevices[0]->mDeviceType;
2701 if (profileType & inputDeviceTypes) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07002702 sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(inProfile);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002703
2704 inputDesc->mInputSource = AUDIO_SOURCE_MIC;
Eric Laurent83b88082014-06-20 18:31:16 -07002705 inputDesc->mDevice = profileType;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002706
Eric Laurentcf2c0212014-07-25 16:20:43 -07002707 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2708 config.sample_rate = inputDesc->mSamplingRate;
2709 config.channel_mask = inputDesc->mChannelMask;
2710 config.format = inputDesc->mFormat;
2711 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
2712 status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,
2713 &input,
2714 &config,
2715 &inputDesc->mDevice,
2716 String8(""),
2717 AUDIO_SOURCE_MIC,
2718 AUDIO_INPUT_FLAG_NONE);
2719
2720 if (status == NO_ERROR) {
Eric Laurent5b61ddd2014-05-07 09:10:01 -07002721 for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002722 audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;
Eric Laurent3a4311c2014-03-17 12:00:47 -07002723 ssize_t index =
Eric Laurent5b61ddd2014-05-07 09:10:01 -07002724 mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002725 // give a valid ID to an attached device once confirmed it is reachable
2726 if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) {
2727 mAvailableInputDevices[index]->mId = nextUniqueId();
Eric Laurent6a94d692014-05-20 11:18:06 -07002728 mAvailableInputDevices[index]->mModule = mHwModules[i];
Eric Laurent3a4311c2014-03-17 12:00:47 -07002729 }
2730 }
2731 mpClientInterface->closeInput(input);
2732 } else {
2733 ALOGW("Cannot open input stream for device %08x on hw module %s",
2734 inputDesc->mDevice,
2735 mHwModules[i]->mName);
2736 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002737 }
2738 }
2739 }
2740 // make sure all attached devices have been allocated a unique ID
2741 for (size_t i = 0; i < mAvailableOutputDevices.size();) {
2742 if (mAvailableOutputDevices[i]->mId == 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002743 ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002744 mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
2745 continue;
2746 }
2747 i++;
2748 }
2749 for (size_t i = 0; i < mAvailableInputDevices.size();) {
2750 if (mAvailableInputDevices[i]->mId == 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002751 ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002752 mAvailableInputDevices.remove(mAvailableInputDevices[i]);
2753 continue;
2754 }
2755 i++;
2756 }
2757 // make sure default device is reachable
2758 if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07002759 ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType);
Eric Laurent3a4311c2014-03-17 12:00:47 -07002760 }
Eric Laurente552edb2014-03-10 17:42:56 -07002761
2762 ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
2763
2764 updateDevicesAndOutputs();
2765
2766#ifdef AUDIO_POLICY_TEST
2767 if (mPrimaryOutput != 0) {
2768 AudioParameter outputCmd = AudioParameter();
2769 outputCmd.addInt(String8("set_id"), 0);
2770 mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
2771
2772 mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
2773 mTestSamplingRate = 44100;
Eric Laurent3b73df72014-03-11 09:06:29 -07002774 mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
2775 mTestChannels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07002776 mTestLatencyMs = 0;
2777 mCurOutput = 0;
2778 mDirectOutput = false;
2779 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
2780 mTestOutputs[i] = 0;
2781 }
2782
2783 const size_t SIZE = 256;
2784 char buffer[SIZE];
2785 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
2786 run(buffer, ANDROID_PRIORITY_AUDIO);
2787 }
2788#endif //AUDIO_POLICY_TEST
2789}
2790
Eric Laurente0720872014-03-11 09:30:41 -07002791AudioPolicyManager::~AudioPolicyManager()
Eric Laurente552edb2014-03-10 17:42:56 -07002792{
2793#ifdef AUDIO_POLICY_TEST
2794 exit();
2795#endif //AUDIO_POLICY_TEST
2796 for (size_t i = 0; i < mOutputs.size(); i++) {
2797 mpClientInterface->closeOutput(mOutputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002798 }
2799 for (size_t i = 0; i < mInputs.size(); i++) {
2800 mpClientInterface->closeInput(mInputs.keyAt(i));
Eric Laurente552edb2014-03-10 17:42:56 -07002801 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07002802 mAvailableOutputDevices.clear();
2803 mAvailableInputDevices.clear();
Eric Laurent1f2f2232014-06-02 12:01:23 -07002804 mOutputs.clear();
2805 mInputs.clear();
2806 mHwModules.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07002807}
2808
Eric Laurente0720872014-03-11 09:30:41 -07002809status_t AudioPolicyManager::initCheck()
Eric Laurente552edb2014-03-10 17:42:56 -07002810{
2811 return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
2812}
2813
2814#ifdef AUDIO_POLICY_TEST
Eric Laurente0720872014-03-11 09:30:41 -07002815bool AudioPolicyManager::threadLoop()
Eric Laurente552edb2014-03-10 17:42:56 -07002816{
2817 ALOGV("entering threadLoop()");
2818 while (!exitPending())
2819 {
2820 String8 command;
2821 int valueInt;
2822 String8 value;
2823
2824 Mutex::Autolock _l(mLock);
2825 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
2826
2827 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
2828 AudioParameter param = AudioParameter(command);
2829
2830 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
2831 valueInt != 0) {
2832 ALOGV("Test command %s received", command.string());
2833 String8 target;
2834 if (param.get(String8("target"), target) != NO_ERROR) {
2835 target = "Manager";
2836 }
2837 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
2838 param.remove(String8("test_cmd_policy_output"));
2839 mCurOutput = valueInt;
2840 }
2841 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
2842 param.remove(String8("test_cmd_policy_direct"));
2843 if (value == "false") {
2844 mDirectOutput = false;
2845 } else if (value == "true") {
2846 mDirectOutput = true;
2847 }
2848 }
2849 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
2850 param.remove(String8("test_cmd_policy_input"));
2851 mTestInput = valueInt;
2852 }
2853
2854 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
2855 param.remove(String8("test_cmd_policy_format"));
Eric Laurent3b73df72014-03-11 09:06:29 -07002856 int format = AUDIO_FORMAT_INVALID;
Eric Laurente552edb2014-03-10 17:42:56 -07002857 if (value == "PCM 16 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002858 format = AUDIO_FORMAT_PCM_16_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07002859 } else if (value == "PCM 8 bits") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002860 format = AUDIO_FORMAT_PCM_8_BIT;
Eric Laurente552edb2014-03-10 17:42:56 -07002861 } else if (value == "Compressed MP3") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002862 format = AUDIO_FORMAT_MP3;
Eric Laurente552edb2014-03-10 17:42:56 -07002863 }
Eric Laurent3b73df72014-03-11 09:06:29 -07002864 if (format != AUDIO_FORMAT_INVALID) {
Eric Laurente552edb2014-03-10 17:42:56 -07002865 if (target == "Manager") {
2866 mTestFormat = format;
2867 } else if (mTestOutputs[mCurOutput] != 0) {
2868 AudioParameter outputParam = AudioParameter();
2869 outputParam.addInt(String8("format"), format);
2870 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2871 }
2872 }
2873 }
2874 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
2875 param.remove(String8("test_cmd_policy_channels"));
2876 int channels = 0;
2877
2878 if (value == "Channels Stereo") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002879 channels = AUDIO_CHANNEL_OUT_STEREO;
Eric Laurente552edb2014-03-10 17:42:56 -07002880 } else if (value == "Channels Mono") {
Eric Laurent3b73df72014-03-11 09:06:29 -07002881 channels = AUDIO_CHANNEL_OUT_MONO;
Eric Laurente552edb2014-03-10 17:42:56 -07002882 }
2883 if (channels != 0) {
2884 if (target == "Manager") {
2885 mTestChannels = channels;
2886 } else if (mTestOutputs[mCurOutput] != 0) {
2887 AudioParameter outputParam = AudioParameter();
2888 outputParam.addInt(String8("channels"), channels);
2889 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2890 }
2891 }
2892 }
2893 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
2894 param.remove(String8("test_cmd_policy_sampleRate"));
2895 if (valueInt >= 0 && valueInt <= 96000) {
2896 int samplingRate = valueInt;
2897 if (target == "Manager") {
2898 mTestSamplingRate = samplingRate;
2899 } else if (mTestOutputs[mCurOutput] != 0) {
2900 AudioParameter outputParam = AudioParameter();
2901 outputParam.addInt(String8("sampling_rate"), samplingRate);
2902 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
2903 }
2904 }
2905 }
2906
2907 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
2908 param.remove(String8("test_cmd_policy_reopen"));
2909
Eric Laurent1f2f2232014-06-02 12:01:23 -07002910 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07002911 mpClientInterface->closeOutput(mPrimaryOutput);
2912
2913 audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
2914
Eric Laurente552edb2014-03-10 17:42:56 -07002915 mOutputs.removeItem(mPrimaryOutput);
2916
Eric Laurent1f2f2232014-06-02 12:01:23 -07002917 sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
Eric Laurente552edb2014-03-10 17:42:56 -07002918 outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurentcf2c0212014-07-25 16:20:43 -07002919 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
2920 config.sample_rate = outputDesc->mSamplingRate;
2921 config.channel_mask = outputDesc->mChannelMask;
2922 config.format = outputDesc->mFormat;
2923 status_t status = mpClientInterface->openOutput(moduleHandle,
2924 &mPrimaryOutput,
2925 &config,
2926 &outputDesc->mDevice,
2927 String8(""),
2928 &outputDesc->mLatency,
2929 outputDesc->mFlags);
2930 if (status != NO_ERROR) {
2931 ALOGE("Failed to reopen hardware output stream, "
2932 "samplingRate: %d, format %d, channels %d",
2933 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
Eric Laurente552edb2014-03-10 17:42:56 -07002934 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07002935 outputDesc->mSamplingRate = config.sample_rate;
2936 outputDesc->mChannelMask = config.channel_mask;
2937 outputDesc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07002938 AudioParameter outputCmd = AudioParameter();
2939 outputCmd.addInt(String8("set_id"), 0);
2940 mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
2941 addOutput(mPrimaryOutput, outputDesc);
2942 }
2943 }
2944
2945
2946 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
2947 }
2948 }
2949 return false;
2950}
2951
Eric Laurente0720872014-03-11 09:30:41 -07002952void AudioPolicyManager::exit()
Eric Laurente552edb2014-03-10 17:42:56 -07002953{
2954 {
2955 AutoMutex _l(mLock);
2956 requestExit();
2957 mWaitWorkCV.signal();
2958 }
2959 requestExitAndWait();
2960}
2961
Eric Laurente0720872014-03-11 09:30:41 -07002962int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07002963{
2964 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
2965 if (output == mTestOutputs[i]) return i;
2966 }
2967 return 0;
2968}
2969#endif //AUDIO_POLICY_TEST
2970
2971// ---
2972
Eric Laurent1f2f2232014-06-02 12:01:23 -07002973void AudioPolicyManager::addOutput(audio_io_handle_t output, sp<AudioOutputDescriptor> outputDesc)
Eric Laurente552edb2014-03-10 17:42:56 -07002974{
Eric Laurent1c333e22014-05-20 10:48:17 -07002975 outputDesc->mIoHandle = output;
2976 outputDesc->mId = nextUniqueId();
2977 mOutputs.add(output, outputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07002978 nextAudioPortGeneration();
Eric Laurente552edb2014-03-10 17:42:56 -07002979}
2980
Eric Laurent1f2f2232014-06-02 12:01:23 -07002981void AudioPolicyManager::addInput(audio_io_handle_t input, sp<AudioInputDescriptor> inputDesc)
Eric Laurentd4692962014-05-05 18:13:44 -07002982{
Eric Laurent1c333e22014-05-20 10:48:17 -07002983 inputDesc->mIoHandle = input;
2984 inputDesc->mId = nextUniqueId();
2985 mInputs.add(input, inputDesc);
Eric Laurent6a94d692014-05-20 11:18:06 -07002986 nextAudioPortGeneration();
Eric Laurentd4692962014-05-05 18:13:44 -07002987}
Eric Laurente552edb2014-03-10 17:42:56 -07002988
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07002989void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
2990 const String8 address /*in*/,
2991 SortedVector<audio_io_handle_t>& outputs /*out*/) {
2992 // look for a match on the given address on the addresses of the outputs:
2993 // find the address by finding the patch that maps to this output
2994 ssize_t patchIdx = mAudioPatches.indexOfKey(desc->mPatchHandle);
2995 //ALOGV(" inspecting output %d (patch %d) for supported device=0x%x",
2996 // outputIdx, patchIdx, desc->mProfile->mSupportedDevices.types());
2997 if (patchIdx >= 0) {
2998 const sp<AudioPatch> patchDesc = mAudioPatches.valueAt(patchIdx);
2999 const int numSinks = patchDesc->mPatch.num_sinks;
3000 for (ssize_t j=0; j < numSinks; j++) {
3001 if (patchDesc->mPatch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) {
3002 const char* patchAddr =
3003 patchDesc->mPatch.sinks[j].ext.device.address;
3004 if (strncmp(patchAddr,
3005 address.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003006 ALOGV("findIoHandlesByAddress(): adding opened output %d on same address %s",
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003007 desc->mIoHandle, patchDesc->mPatch.sinks[j].ext.device.address);
3008 outputs.add(desc->mIoHandle);
3009 break;
3010 }
3011 }
3012 }
3013 }
3014}
3015
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003016status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor> devDesc,
Eric Laurent3b73df72014-03-11 09:06:29 -07003017 audio_policy_dev_state_t state,
Eric Laurente552edb2014-03-10 17:42:56 -07003018 SortedVector<audio_io_handle_t>& outputs,
Eric Laurent3a4311c2014-03-17 12:00:47 -07003019 const String8 address)
Eric Laurente552edb2014-03-10 17:42:56 -07003020{
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003021 audio_devices_t device = devDesc->mDeviceType;
Eric Laurent1f2f2232014-06-02 12:01:23 -07003022 sp<AudioOutputDescriptor> desc;
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003023 // erase all current sample rates, formats and channel masks
3024 devDesc->clearCapabilities();
Eric Laurente552edb2014-03-10 17:42:56 -07003025
Eric Laurent3b73df72014-03-11 09:06:29 -07003026 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003027 // first list already open outputs that can be routed to this device
3028 for (size_t i = 0; i < mOutputs.size(); i++) {
3029 desc = mOutputs.valueAt(i);
Eric Laurent3a4311c2014-03-17 12:00:47 -07003030 if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003031 if (!deviceDistinguishesOnAddress(device)) {
3032 ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
3033 outputs.add(mOutputs.keyAt(i));
3034 } else {
3035 ALOGV(" checking address match due to device 0x%x", device);
3036 findIoHandlesByAddress(desc, address, outputs);
3037 }
Eric Laurente552edb2014-03-10 17:42:56 -07003038 }
3039 }
3040 // then look for output profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07003041 SortedVector< sp<IOProfile> > profiles;
Eric Laurente552edb2014-03-10 17:42:56 -07003042 for (size_t i = 0; i < mHwModules.size(); i++)
3043 {
3044 if (mHwModules[i]->mHandle == 0) {
3045 continue;
3046 }
3047 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3048 {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003049 if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
Eric Laurentd4692962014-05-05 18:13:44 -07003050 ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
Eric Laurente552edb2014-03-10 17:42:56 -07003051 profiles.add(mHwModules[i]->mOutputProfiles[j]);
3052 }
3053 }
3054 }
3055
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003056 ALOGV(" found %d profiles, %d outputs", profiles.size(), outputs.size());
3057
Eric Laurente552edb2014-03-10 17:42:56 -07003058 if (profiles.isEmpty() && outputs.isEmpty()) {
3059 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3060 return BAD_VALUE;
3061 }
3062
3063 // open outputs for matching profiles if needed. Direct outputs are also opened to
3064 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3065 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003066 sp<IOProfile> profile = profiles[profile_index];
Eric Laurente552edb2014-03-10 17:42:56 -07003067
3068 // nothing to do if one output is already opened for this profile
3069 size_t j;
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003070 for (j = 0; j < outputs.size(); j++) {
3071 desc = mOutputs.valueFor(outputs.itemAt(j));
Eric Laurente552edb2014-03-10 17:42:56 -07003072 if (!desc->isDuplicated() && desc->mProfile == profile) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003073 // matching profile: save the sample rates, format and channel masks supported
3074 // by the profile in our device descriptor
3075 devDesc->importAudioPort(profile);
Eric Laurente552edb2014-03-10 17:42:56 -07003076 break;
3077 }
3078 }
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003079 if (j != outputs.size()) {
Eric Laurente552edb2014-03-10 17:42:56 -07003080 continue;
3081 }
3082
Eric Laurent83b88082014-06-20 18:31:16 -07003083 ALOGV("opening output for device %08x with params %s profile %p",
3084 device, address.string(), profile.get());
Eric Laurente552edb2014-03-10 17:42:56 -07003085 desc = new AudioOutputDescriptor(profile);
3086 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003087 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3088 config.sample_rate = desc->mSamplingRate;
3089 config.channel_mask = desc->mChannelMask;
3090 config.format = desc->mFormat;
3091 config.offload_info.sample_rate = desc->mSamplingRate;
3092 config.offload_info.channel_mask = desc->mChannelMask;
3093 config.offload_info.format = desc->mFormat;
3094 audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
3095 status_t status = mpClientInterface->openOutput(profile->mModule->mHandle,
3096 &output,
3097 &config,
3098 &desc->mDevice,
3099 address,
3100 &desc->mLatency,
3101 desc->mFlags);
3102 if (status == NO_ERROR) {
3103 desc->mSamplingRate = config.sample_rate;
3104 desc->mChannelMask = config.channel_mask;
3105 desc->mFormat = config.format;
Eric Laurente552edb2014-03-10 17:42:56 -07003106
Eric Laurentd4692962014-05-05 18:13:44 -07003107 // Here is where the out_set_parameters() for card & device gets called
Eric Laurent3a4311c2014-03-17 12:00:47 -07003108 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003109 char *param = audio_device_address_to_parameter(device, address);
3110 mpClientInterface->setParameters(output, String8(param));
3111 free(param);
Eric Laurente552edb2014-03-10 17:42:56 -07003112 }
3113
Eric Laurentd4692962014-05-05 18:13:44 -07003114 // Here is where we step through and resolve any "dynamic" fields
3115 String8 reply;
3116 char *value;
3117 if (profile->mSamplingRates[0] == 0) {
3118 reply = mpClientInterface->getParameters(output,
3119 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003120 ALOGV("checkOutputsForDevice() supported sampling rates %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003121 reply.string());
3122 value = strpbrk((char *)reply.string(), "=");
3123 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003124 profile->loadSamplingRates(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003125 }
Eric Laurentd4692962014-05-05 18:13:44 -07003126 }
3127 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3128 reply = mpClientInterface->getParameters(output,
3129 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003130 ALOGV("checkOutputsForDevice() supported formats %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003131 reply.string());
3132 value = strpbrk((char *)reply.string(), "=");
3133 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003134 profile->loadFormats(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003135 }
Eric Laurentd4692962014-05-05 18:13:44 -07003136 }
3137 if (profile->mChannelMasks[0] == 0) {
3138 reply = mpClientInterface->getParameters(output,
3139 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003140 ALOGV("checkOutputsForDevice() supported channel masks %s",
Eric Laurentd4692962014-05-05 18:13:44 -07003141 reply.string());
3142 value = strpbrk((char *)reply.string(), "=");
3143 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003144 profile->loadOutChannels(value + 1);
Eric Laurente552edb2014-03-10 17:42:56 -07003145 }
Eric Laurentd4692962014-05-05 18:13:44 -07003146 }
3147 if (((profile->mSamplingRates[0] == 0) &&
3148 (profile->mSamplingRates.size() < 2)) ||
3149 ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
3150 (profile->mFormats.size() < 2)) ||
3151 ((profile->mChannelMasks[0] == 0) &&
3152 (profile->mChannelMasks.size() < 2))) {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003153 ALOGW("checkOutputsForDevice() missing param");
Eric Laurentd4692962014-05-05 18:13:44 -07003154 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003155 output = AUDIO_IO_HANDLE_NONE;
Eric Laurent1e693b52014-07-09 15:03:28 -07003156 } else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 ||
3157 profile->mChannelMasks[0] == 0) {
Eric Laurentd4692962014-05-05 18:13:44 -07003158 mpClientInterface->closeOutput(output);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003159 config.sample_rate = profile->pickSamplingRate();
3160 config.channel_mask = profile->pickChannelMask();
3161 config.format = profile->pickFormat();
3162 config.offload_info.sample_rate = config.sample_rate;
3163 config.offload_info.channel_mask = config.channel_mask;
3164 config.offload_info.format = config.format;
3165 status = mpClientInterface->openOutput(profile->mModule->mHandle,
3166 &output,
3167 &config,
3168 &desc->mDevice,
3169 address,
3170 &desc->mLatency,
3171 desc->mFlags);
3172 if (status == NO_ERROR) {
3173 desc->mSamplingRate = config.sample_rate;
3174 desc->mChannelMask = config.channel_mask;
3175 desc->mFormat = config.format;
3176 } else {
3177 output = AUDIO_IO_HANDLE_NONE;
3178 }
Eric Laurentd4692962014-05-05 18:13:44 -07003179 }
3180
Eric Laurentcf2c0212014-07-25 16:20:43 -07003181 if (output != AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003182 addOutput(output, desc);
Eric Laurentd4692962014-05-05 18:13:44 -07003183 if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003184 audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003185
Eric Laurentd4692962014-05-05 18:13:44 -07003186 // set initial stream volume for device
3187 applyStreamVolumes(output, device, 0, true);
Eric Laurente552edb2014-03-10 17:42:56 -07003188
Eric Laurentd4692962014-05-05 18:13:44 -07003189 //TODO: configure audio effect output stage here
3190
3191 // open a duplicating output thread for the new output and the primary output
3192 duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
3193 mPrimaryOutput);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003194 if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003195 // add duplicated output descriptor
Eric Laurentcf2c0212014-07-25 16:20:43 -07003196 sp<AudioOutputDescriptor> dupOutputDesc =
3197 new AudioOutputDescriptor(NULL);
Eric Laurentd4692962014-05-05 18:13:44 -07003198 dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
3199 dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
3200 dupOutputDesc->mSamplingRate = desc->mSamplingRate;
3201 dupOutputDesc->mFormat = desc->mFormat;
3202 dupOutputDesc->mChannelMask = desc->mChannelMask;
3203 dupOutputDesc->mLatency = desc->mLatency;
3204 addOutput(duplicatedOutput, dupOutputDesc);
3205 applyStreamVolumes(duplicatedOutput, device, 0, true);
3206 } else {
3207 ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
3208 mPrimaryOutput, output);
3209 mpClientInterface->closeOutput(output);
3210 mOutputs.removeItem(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07003211 nextAudioPortGeneration();
Eric Laurentcf2c0212014-07-25 16:20:43 -07003212 output = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003213 }
Eric Laurente552edb2014-03-10 17:42:56 -07003214 }
3215 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003216 } else {
3217 output = AUDIO_IO_HANDLE_NONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003218 }
Eric Laurentcf2c0212014-07-25 16:20:43 -07003219 if (output == AUDIO_IO_HANDLE_NONE) {
Eric Laurente552edb2014-03-10 17:42:56 -07003220 ALOGW("checkOutputsForDevice() could not open output for device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07003221 profiles.removeAt(profile_index);
3222 profile_index--;
3223 } else {
3224 outputs.add(output);
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07003225 devDesc->importAudioPort(profile);
3226
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003227 if (deviceDistinguishesOnAddress(device)) {
3228 ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)",
3229 device, address.string());
3230 setOutputDevice(output, device, true/*force*/, 0/*delay*/,
3231 NULL/*patch handle*/, address.string());
3232 }
Eric Laurente552edb2014-03-10 17:42:56 -07003233 ALOGV("checkOutputsForDevice(): adding output %d", output);
3234 }
3235 }
3236
3237 if (profiles.isEmpty()) {
3238 ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
3239 return BAD_VALUE;
3240 }
Eric Laurentd4692962014-05-05 18:13:44 -07003241 } else { // Disconnect
Eric Laurente552edb2014-03-10 17:42:56 -07003242 // check if one opened output is not needed any more after disconnecting one device
3243 for (size_t i = 0; i < mOutputs.size(); i++) {
3244 desc = mOutputs.valueAt(i);
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07003245 if (!desc->isDuplicated()) {
3246 if (!(desc->mProfile->mSupportedDevices.types()
3247 & mAvailableOutputDevices.types())) {
3248 ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
3249 mOutputs.keyAt(i));
3250 outputs.add(mOutputs.keyAt(i));
3251 } else if (deviceDistinguishesOnAddress(device) &&
3252 // exact match on device
3253 (desc->mProfile->mSupportedDevices.types() == device)) {
3254 findIoHandlesByAddress(desc, address, outputs);
3255 }
Eric Laurente552edb2014-03-10 17:42:56 -07003256 }
3257 }
Eric Laurentd4692962014-05-05 18:13:44 -07003258 // Clear any profiles associated with the disconnected device.
Eric Laurente552edb2014-03-10 17:42:56 -07003259 for (size_t i = 0; i < mHwModules.size(); i++)
3260 {
3261 if (mHwModules[i]->mHandle == 0) {
3262 continue;
3263 }
3264 for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
3265 {
Eric Laurent1c333e22014-05-20 10:48:17 -07003266 sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07003267 if (profile->mSupportedDevices.types() & device) {
3268 ALOGV("checkOutputsForDevice(): "
3269 "clearing direct output profile %zu on module %zu", j, i);
Eric Laurente552edb2014-03-10 17:42:56 -07003270 if (profile->mSamplingRates[0] == 0) {
3271 profile->mSamplingRates.clear();
3272 profile->mSamplingRates.add(0);
3273 }
3274 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3275 profile->mFormats.clear();
3276 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3277 }
3278 if (profile->mChannelMasks[0] == 0) {
3279 profile->mChannelMasks.clear();
3280 profile->mChannelMasks.add(0);
3281 }
3282 }
3283 }
3284 }
3285 }
3286 return NO_ERROR;
3287}
3288
Eric Laurentd4692962014-05-05 18:13:44 -07003289status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,
3290 audio_policy_dev_state_t state,
3291 SortedVector<audio_io_handle_t>& inputs,
3292 const String8 address)
3293{
Eric Laurent1f2f2232014-06-02 12:01:23 -07003294 sp<AudioInputDescriptor> desc;
Eric Laurentd4692962014-05-05 18:13:44 -07003295 if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
3296 // first list already open inputs that can be routed to this device
3297 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3298 desc = mInputs.valueAt(input_index);
3299 if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
3300 ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
3301 inputs.add(mInputs.keyAt(input_index));
3302 }
3303 }
3304
3305 // then look for input profiles that can be routed to this device
Eric Laurent1c333e22014-05-20 10:48:17 -07003306 SortedVector< sp<IOProfile> > profiles;
Eric Laurentd4692962014-05-05 18:13:44 -07003307 for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
3308 {
3309 if (mHwModules[module_idx]->mHandle == 0) {
3310 continue;
3311 }
3312 for (size_t profile_index = 0;
3313 profile_index < mHwModules[module_idx]->mInputProfiles.size();
3314 profile_index++)
3315 {
3316 if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types()
3317 & (device & ~AUDIO_DEVICE_BIT_IN)) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07003318 ALOGV("checkInputsForDevice(): adding profile %zu from module %zu",
Eric Laurentd4692962014-05-05 18:13:44 -07003319 profile_index, module_idx);
3320 profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]);
3321 }
3322 }
3323 }
3324
3325 if (profiles.isEmpty() && inputs.isEmpty()) {
3326 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3327 return BAD_VALUE;
3328 }
3329
3330 // open inputs for matching profiles if needed. Direct inputs are also opened to
3331 // query for dynamic parameters and will be closed later by setDeviceConnectionState()
3332 for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
3333
Eric Laurent1c333e22014-05-20 10:48:17 -07003334 sp<IOProfile> profile = profiles[profile_index];
Eric Laurentd4692962014-05-05 18:13:44 -07003335 // nothing to do if one input is already opened for this profile
3336 size_t input_index;
3337 for (input_index = 0; input_index < mInputs.size(); input_index++) {
3338 desc = mInputs.valueAt(input_index);
3339 if (desc->mProfile == profile) {
3340 break;
3341 }
3342 }
3343 if (input_index != mInputs.size()) {
3344 continue;
3345 }
3346
3347 ALOGV("opening input for device 0x%X with params %s", device, address.string());
3348 desc = new AudioInputDescriptor(profile);
3349 desc->mDevice = device;
Eric Laurentcf2c0212014-07-25 16:20:43 -07003350 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
3351 config.sample_rate = desc->mSamplingRate;
3352 config.channel_mask = desc->mChannelMask;
3353 config.format = desc->mFormat;
3354 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
3355 status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
3356 &input,
3357 &config,
3358 &desc->mDevice,
3359 address,
3360 AUDIO_SOURCE_MIC,
3361 AUDIO_INPUT_FLAG_NONE /*FIXME*/);
Eric Laurentd4692962014-05-05 18:13:44 -07003362
Eric Laurentcf2c0212014-07-25 16:20:43 -07003363 if (status == NO_ERROR) {
3364 desc->mSamplingRate = config.sample_rate;
3365 desc->mChannelMask = config.channel_mask;
3366 desc->mFormat = config.format;
Eric Laurentd4692962014-05-05 18:13:44 -07003367
Eric Laurentd4692962014-05-05 18:13:44 -07003368 if (!address.isEmpty()) {
Eric Laurentcf2c0212014-07-25 16:20:43 -07003369 char *param = audio_device_address_to_parameter(device, address);
3370 mpClientInterface->setParameters(input, String8(param));
3371 free(param);
Eric Laurentd4692962014-05-05 18:13:44 -07003372 }
3373
3374 // Here is where we step through and resolve any "dynamic" fields
3375 String8 reply;
3376 char *value;
3377 if (profile->mSamplingRates[0] == 0) {
3378 reply = mpClientInterface->getParameters(input,
3379 String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
3380 ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
3381 reply.string());
3382 value = strpbrk((char *)reply.string(), "=");
3383 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003384 profile->loadSamplingRates(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003385 }
3386 }
3387 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3388 reply = mpClientInterface->getParameters(input,
3389 String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
3390 ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
3391 value = strpbrk((char *)reply.string(), "=");
3392 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003393 profile->loadFormats(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003394 }
3395 }
3396 if (profile->mChannelMasks[0] == 0) {
3397 reply = mpClientInterface->getParameters(input,
3398 String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
3399 ALOGV("checkInputsForDevice() direct input sup channel masks %s",
3400 reply.string());
3401 value = strpbrk((char *)reply.string(), "=");
3402 if (value != NULL) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003403 profile->loadInChannels(value + 1);
Eric Laurentd4692962014-05-05 18:13:44 -07003404 }
3405 }
3406 if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
3407 ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
3408 ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
3409 ALOGW("checkInputsForDevice() direct input missing param");
3410 mpClientInterface->closeInput(input);
Eric Laurentcf2c0212014-07-25 16:20:43 -07003411 input = AUDIO_IO_HANDLE_NONE;
Eric Laurentd4692962014-05-05 18:13:44 -07003412 }
3413
3414 if (input != 0) {
3415 addInput(input, desc);
3416 }
3417 } // endif input != 0
3418
Eric Laurentcf2c0212014-07-25 16:20:43 -07003419 if (input == AUDIO_IO_HANDLE_NONE) {
Eric Laurentd4692962014-05-05 18:13:44 -07003420 ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
Eric Laurentd4692962014-05-05 18:13:44 -07003421 profiles.removeAt(profile_index);
3422 profile_index--;
3423 } else {
3424 inputs.add(input);
3425 ALOGV("checkInputsForDevice(): adding input %d", input);
3426 }
3427 } // end scan profiles
3428
3429 if (profiles.isEmpty()) {
3430 ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
3431 return BAD_VALUE;
3432 }
3433 } else {
3434 // Disconnect
3435 // check if one opened input is not needed any more after disconnecting one device
3436 for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
3437 desc = mInputs.valueAt(input_index);
3438 if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) {
3439 ALOGV("checkInputsForDevice(): disconnecting adding input %d",
3440 mInputs.keyAt(input_index));
3441 inputs.add(mInputs.keyAt(input_index));
3442 }
3443 }
3444 // Clear any profiles associated with the disconnected device.
3445 for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
3446 if (mHwModules[module_index]->mHandle == 0) {
3447 continue;
3448 }
3449 for (size_t profile_index = 0;
3450 profile_index < mHwModules[module_index]->mInputProfiles.size();
3451 profile_index++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07003452 sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
Eric Laurentd4692962014-05-05 18:13:44 -07003453 if (profile->mSupportedDevices.types() & device) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07003454 ALOGV("checkInputsForDevice(): clearing direct input profile %zu on module %zu",
Eric Laurentd4692962014-05-05 18:13:44 -07003455 profile_index, module_index);
3456 if (profile->mSamplingRates[0] == 0) {
3457 profile->mSamplingRates.clear();
3458 profile->mSamplingRates.add(0);
3459 }
3460 if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
3461 profile->mFormats.clear();
3462 profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
3463 }
3464 if (profile->mChannelMasks[0] == 0) {
3465 profile->mChannelMasks.clear();
3466 profile->mChannelMasks.add(0);
3467 }
3468 }
3469 }
3470 }
3471 } // end disconnect
3472
3473 return NO_ERROR;
3474}
3475
3476
Eric Laurente0720872014-03-11 09:30:41 -07003477void AudioPolicyManager::closeOutput(audio_io_handle_t output)
Eric Laurente552edb2014-03-10 17:42:56 -07003478{
3479 ALOGV("closeOutput(%d)", output);
3480
Eric Laurent1f2f2232014-06-02 12:01:23 -07003481 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003482 if (outputDesc == NULL) {
3483 ALOGW("closeOutput() unknown output %d", output);
3484 return;
3485 }
3486
3487 // look for duplicated outputs connected to the output being removed.
3488 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003489 sp<AudioOutputDescriptor> dupOutputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07003490 if (dupOutputDesc->isDuplicated() &&
3491 (dupOutputDesc->mOutput1 == outputDesc ||
3492 dupOutputDesc->mOutput2 == outputDesc)) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003493 sp<AudioOutputDescriptor> outputDesc2;
Eric Laurente552edb2014-03-10 17:42:56 -07003494 if (dupOutputDesc->mOutput1 == outputDesc) {
3495 outputDesc2 = dupOutputDesc->mOutput2;
3496 } else {
3497 outputDesc2 = dupOutputDesc->mOutput1;
3498 }
3499 // As all active tracks on duplicated output will be deleted,
3500 // and as they were also referenced on the other output, the reference
3501 // count for their stream type must be adjusted accordingly on
3502 // the other output.
Eric Laurent3b73df72014-03-11 09:06:29 -07003503 for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
Eric Laurente552edb2014-03-10 17:42:56 -07003504 int refCount = dupOutputDesc->mRefCount[j];
Eric Laurent3b73df72014-03-11 09:06:29 -07003505 outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
Eric Laurente552edb2014-03-10 17:42:56 -07003506 }
3507 audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
3508 ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
3509
3510 mpClientInterface->closeOutput(duplicatedOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07003511 mOutputs.removeItem(duplicatedOutput);
3512 }
3513 }
3514
3515 AudioParameter param;
3516 param.add(String8("closing"), String8("true"));
3517 mpClientInterface->setParameters(output, param.toString());
3518
3519 mpClientInterface->closeOutput(output);
Eric Laurente552edb2014-03-10 17:42:56 -07003520 mOutputs.removeItem(output);
3521 mPreviousOutputs = mOutputs;
Eric Laurent6a94d692014-05-20 11:18:06 -07003522 nextAudioPortGeneration();
Eric Laurente552edb2014-03-10 17:42:56 -07003523}
3524
Eric Laurente0720872014-03-11 09:30:41 -07003525SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
Eric Laurent1f2f2232014-06-02 12:01:23 -07003526 DefaultKeyedVector<audio_io_handle_t, sp<AudioOutputDescriptor> > openOutputs)
Eric Laurente552edb2014-03-10 17:42:56 -07003527{
3528 SortedVector<audio_io_handle_t> outputs;
3529
3530 ALOGVV("getOutputsForDevice() device %04x", device);
3531 for (size_t i = 0; i < openOutputs.size(); i++) {
3532 ALOGVV("output %d isDuplicated=%d device=%04x",
3533 i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
3534 if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
3535 ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
3536 outputs.add(openOutputs.keyAt(i));
3537 }
3538 }
3539 return outputs;
3540}
3541
Eric Laurente0720872014-03-11 09:30:41 -07003542bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
Eric Laurente552edb2014-03-10 17:42:56 -07003543 SortedVector<audio_io_handle_t>& outputs2)
3544{
3545 if (outputs1.size() != outputs2.size()) {
3546 return false;
3547 }
3548 for (size_t i = 0; i < outputs1.size(); i++) {
3549 if (outputs1[i] != outputs2[i]) {
3550 return false;
3551 }
3552 }
3553 return true;
3554}
3555
Eric Laurente0720872014-03-11 09:30:41 -07003556void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
Eric Laurente552edb2014-03-10 17:42:56 -07003557{
3558 audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
3559 audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
3560 SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
3561 SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
3562
3563 if (!vectorsEqual(srcOutputs,dstOutputs)) {
3564 ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
3565 strategy, srcOutputs[0], dstOutputs[0]);
3566 // mute strategy while moving tracks from one output to another
3567 for (size_t i = 0; i < srcOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003568 sp<AudioOutputDescriptor> desc = mOutputs.valueFor(srcOutputs[i]);
Eric Laurente552edb2014-03-10 17:42:56 -07003569 if (desc->isStrategyActive(strategy)) {
3570 setStrategyMute(strategy, true, srcOutputs[i]);
3571 setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
3572 }
3573 }
3574
3575 // Move effects associated to this strategy from previous output to new output
3576 if (strategy == STRATEGY_MEDIA) {
3577 audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
3578 SortedVector<audio_io_handle_t> moved;
3579 for (size_t i = 0; i < mEffects.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003580 sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
3581 if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
3582 effectDesc->mIo != fxOutput) {
3583 if (moved.indexOf(effectDesc->mIo) < 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07003584 ALOGV("checkOutputForStrategy() moving effect %d to output %d",
3585 mEffects.keyAt(i), fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003586 mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
Eric Laurente552edb2014-03-10 17:42:56 -07003587 fxOutput);
Eric Laurent1f2f2232014-06-02 12:01:23 -07003588 moved.add(effectDesc->mIo);
Eric Laurente552edb2014-03-10 17:42:56 -07003589 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07003590 effectDesc->mIo = fxOutput;
Eric Laurente552edb2014-03-10 17:42:56 -07003591 }
3592 }
3593 }
3594 // Move tracks associated to this strategy from previous output to new output
Eric Laurent3b73df72014-03-11 09:06:29 -07003595 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
3596 if (getStrategy((audio_stream_type_t)i) == strategy) {
3597 mpClientInterface->invalidateStream((audio_stream_type_t)i);
Eric Laurente552edb2014-03-10 17:42:56 -07003598 }
3599 }
3600 }
3601}
3602
Eric Laurente0720872014-03-11 09:30:41 -07003603void AudioPolicyManager::checkOutputForAllStrategies()
Eric Laurente552edb2014-03-10 17:42:56 -07003604{
3605 checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
3606 checkOutputForStrategy(STRATEGY_PHONE);
3607 checkOutputForStrategy(STRATEGY_SONIFICATION);
3608 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
3609 checkOutputForStrategy(STRATEGY_MEDIA);
3610 checkOutputForStrategy(STRATEGY_DTMF);
3611}
3612
Eric Laurente0720872014-03-11 09:30:41 -07003613audio_io_handle_t AudioPolicyManager::getA2dpOutput()
Eric Laurente552edb2014-03-10 17:42:56 -07003614{
Eric Laurente552edb2014-03-10 17:42:56 -07003615 for (size_t i = 0; i < mOutputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003616 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07003617 if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
3618 return mOutputs.keyAt(i);
3619 }
3620 }
3621
3622 return 0;
3623}
3624
Eric Laurente0720872014-03-11 09:30:41 -07003625void AudioPolicyManager::checkA2dpSuspend()
Eric Laurente552edb2014-03-10 17:42:56 -07003626{
Eric Laurente552edb2014-03-10 17:42:56 -07003627 audio_io_handle_t a2dpOutput = getA2dpOutput();
3628 if (a2dpOutput == 0) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003629 mA2dpSuspended = false;
Eric Laurente552edb2014-03-10 17:42:56 -07003630 return;
3631 }
3632
Eric Laurent3a4311c2014-03-17 12:00:47 -07003633 bool isScoConnected =
3634 (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0;
Eric Laurente552edb2014-03-10 17:42:56 -07003635 // suspend A2DP output if:
3636 // (NOT already suspended) &&
3637 // ((SCO device is connected &&
3638 // (forced usage for communication || for record is SCO))) ||
3639 // (phone state is ringing || in call)
3640 //
3641 // restore A2DP output if:
3642 // (Already suspended) &&
3643 // ((SCO device is NOT connected ||
3644 // (forced usage NOT for communication && NOT for record is SCO))) &&
3645 // (phone state is NOT ringing && NOT in call)
3646 //
3647 if (mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003648 if ((!isScoConnected ||
Eric Laurent3b73df72014-03-11 09:06:29 -07003649 ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) &&
3650 (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) &&
3651 ((mPhoneState != AUDIO_MODE_IN_CALL) &&
3652 (mPhoneState != AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003653
3654 mpClientInterface->restoreOutput(a2dpOutput);
3655 mA2dpSuspended = false;
3656 }
3657 } else {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003658 if ((isScoConnected &&
Eric Laurent3b73df72014-03-11 09:06:29 -07003659 ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
3660 (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) ||
3661 ((mPhoneState == AUDIO_MODE_IN_CALL) ||
3662 (mPhoneState == AUDIO_MODE_RINGTONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07003663
3664 mpClientInterface->suspendOutput(a2dpOutput);
3665 mA2dpSuspended = true;
3666 }
3667 }
3668}
3669
Eric Laurent1c333e22014-05-20 10:48:17 -07003670audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache)
Eric Laurente552edb2014-03-10 17:42:56 -07003671{
3672 audio_devices_t device = AUDIO_DEVICE_NONE;
3673
Eric Laurent1f2f2232014-06-02 12:01:23 -07003674 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07003675
3676 ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
3677 if (index >= 0) {
3678 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3679 if (patchDesc->mUid != mUidCached) {
3680 ALOGV("getNewOutputDevice() device %08x forced by patch %d",
3681 outputDesc->device(), outputDesc->mPatchHandle);
3682 return outputDesc->device();
3683 }
3684 }
3685
Eric Laurente552edb2014-03-10 17:42:56 -07003686 // check the following by order of priority to request a routing change if necessary:
3687 // 1: the strategy enforced audible is active on the output:
3688 // use device for strategy enforced audible
3689 // 2: we are in call or the strategy phone is active on the output:
3690 // use device for strategy phone
3691 // 3: the strategy sonification is active on the output:
3692 // use device for strategy sonification
3693 // 4: the strategy "respectful" sonification is active on the output:
3694 // use device for strategy "respectful" sonification
3695 // 5: the strategy media is active on the output:
3696 // use device for strategy media
3697 // 6: the strategy DTMF is active on the output:
3698 // use device for strategy DTMF
3699 if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
3700 device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
3701 } else if (isInCall() ||
3702 outputDesc->isStrategyActive(STRATEGY_PHONE)) {
3703 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
3704 } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) {
3705 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
3706 } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
3707 device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
3708 } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
3709 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
3710 } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
3711 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
3712 }
3713
Eric Laurent1c333e22014-05-20 10:48:17 -07003714 ALOGV("getNewOutputDevice() selected device %x", device);
3715 return device;
3716}
3717
3718audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
3719{
Eric Laurent1f2f2232014-06-02 12:01:23 -07003720 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07003721
3722 ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
3723 if (index >= 0) {
3724 sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
3725 if (patchDesc->mUid != mUidCached) {
3726 ALOGV("getNewInputDevice() device %08x forced by patch %d",
3727 inputDesc->mDevice, inputDesc->mPatchHandle);
3728 return inputDesc->mDevice;
3729 }
3730 }
3731
Eric Laurent1c333e22014-05-20 10:48:17 -07003732 audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource);
3733
3734 ALOGV("getNewInputDevice() selected device %x", device);
Eric Laurente552edb2014-03-10 17:42:56 -07003735 return device;
3736}
3737
Eric Laurente0720872014-03-11 09:30:41 -07003738uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003739 return (uint32_t)getStrategy(stream);
3740}
3741
Eric Laurente0720872014-03-11 09:30:41 -07003742audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003743 // By checking the range of stream before calling getStrategy, we avoid
3744 // getStrategy's behavior for invalid streams. getStrategy would do a ALOGE
3745 // and then return STRATEGY_MEDIA, but we want to return the empty set.
Eric Laurent3b73df72014-03-11 09:06:29 -07003746 if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) {
Eric Laurent6a94d692014-05-20 11:18:06 -07003747 return AUDIO_DEVICE_NONE;
3748 }
3749 audio_devices_t devices;
3750 AudioPolicyManager::routing_strategy strategy = getStrategy(stream);
3751 devices = getDeviceForStrategy(strategy, true /*fromCache*/);
3752 SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
3753 for (size_t i = 0; i < outputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07003754 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(outputs[i]);
Eric Laurent6a94d692014-05-20 11:18:06 -07003755 if (outputDesc->isStrategyActive(strategy)) {
3756 devices = outputDesc->device();
3757 break;
3758 }
Eric Laurente552edb2014-03-10 17:42:56 -07003759 }
3760 return devices;
3761}
3762
Eric Laurente0720872014-03-11 09:30:41 -07003763AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
Eric Laurent3b73df72014-03-11 09:06:29 -07003764 audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003765 // stream to strategy mapping
3766 switch (stream) {
Eric Laurent3b73df72014-03-11 09:06:29 -07003767 case AUDIO_STREAM_VOICE_CALL:
3768 case AUDIO_STREAM_BLUETOOTH_SCO:
Eric Laurente552edb2014-03-10 17:42:56 -07003769 return STRATEGY_PHONE;
Eric Laurent3b73df72014-03-11 09:06:29 -07003770 case AUDIO_STREAM_RING:
3771 case AUDIO_STREAM_ALARM:
Eric Laurente552edb2014-03-10 17:42:56 -07003772 return STRATEGY_SONIFICATION;
Eric Laurent3b73df72014-03-11 09:06:29 -07003773 case AUDIO_STREAM_NOTIFICATION:
Eric Laurente552edb2014-03-10 17:42:56 -07003774 return STRATEGY_SONIFICATION_RESPECTFUL;
Eric Laurent3b73df72014-03-11 09:06:29 -07003775 case AUDIO_STREAM_DTMF:
Eric Laurente552edb2014-03-10 17:42:56 -07003776 return STRATEGY_DTMF;
3777 default:
3778 ALOGE("unknown stream type");
Eric Laurent3b73df72014-03-11 09:06:29 -07003779 case AUDIO_STREAM_SYSTEM:
Eric Laurente552edb2014-03-10 17:42:56 -07003780 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
3781 // while key clicks are played produces a poor result
Eric Laurent3b73df72014-03-11 09:06:29 -07003782 case AUDIO_STREAM_TTS:
3783 case AUDIO_STREAM_MUSIC:
Eric Laurente552edb2014-03-10 17:42:56 -07003784 return STRATEGY_MEDIA;
Eric Laurent3b73df72014-03-11 09:06:29 -07003785 case AUDIO_STREAM_ENFORCED_AUDIBLE:
Eric Laurente552edb2014-03-10 17:42:56 -07003786 return STRATEGY_ENFORCED_AUDIBLE;
3787 }
3788}
3789
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07003790uint32_t AudioPolicyManager::getStrategyForAttr(const audio_attributes_t *attr) {
3791 // flags to strategy mapping
3792 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
3793 return (uint32_t) STRATEGY_ENFORCED_AUDIBLE;
3794 }
3795
3796 // usage to strategy mapping
3797 switch (attr->usage) {
3798 case AUDIO_USAGE_MEDIA:
3799 case AUDIO_USAGE_GAME:
3800 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
3801 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
3802 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
3803 return (uint32_t) STRATEGY_MEDIA;
3804
3805 case AUDIO_USAGE_VOICE_COMMUNICATION:
3806 return (uint32_t) STRATEGY_PHONE;
3807
3808 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
3809 return (uint32_t) STRATEGY_DTMF;
3810
3811 case AUDIO_USAGE_ALARM:
3812 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
3813 return (uint32_t) STRATEGY_SONIFICATION;
3814
3815 case AUDIO_USAGE_NOTIFICATION:
3816 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
3817 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
3818 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
3819 case AUDIO_USAGE_NOTIFICATION_EVENT:
3820 return (uint32_t) STRATEGY_SONIFICATION_RESPECTFUL;
3821
3822 case AUDIO_USAGE_UNKNOWN:
3823 default:
3824 return (uint32_t) STRATEGY_MEDIA;
3825 }
3826}
3827
Eric Laurente0720872014-03-11 09:30:41 -07003828void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
Eric Laurente552edb2014-03-10 17:42:56 -07003829 switch(stream) {
Eric Laurent3b73df72014-03-11 09:06:29 -07003830 case AUDIO_STREAM_MUSIC:
Eric Laurente552edb2014-03-10 17:42:56 -07003831 checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
3832 updateDevicesAndOutputs();
3833 break;
3834 default:
3835 break;
3836 }
3837}
3838
Eric Laurente0720872014-03-11 09:30:41 -07003839audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
Eric Laurente552edb2014-03-10 17:42:56 -07003840 bool fromCache)
3841{
3842 uint32_t device = AUDIO_DEVICE_NONE;
3843
3844 if (fromCache) {
3845 ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
3846 strategy, mDeviceForStrategy[strategy]);
3847 return mDeviceForStrategy[strategy];
3848 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003849 audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
Eric Laurente552edb2014-03-10 17:42:56 -07003850 switch (strategy) {
3851
3852 case STRATEGY_SONIFICATION_RESPECTFUL:
3853 if (isInCall()) {
3854 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
Eric Laurent3b73df72014-03-11 09:06:29 -07003855 } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
Eric Laurente552edb2014-03-10 17:42:56 -07003856 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
3857 // while media is playing on a remote device, use the the sonification behavior.
3858 // Note that we test this usecase before testing if media is playing because
3859 // the isStreamActive() method only informs about the activity of a stream, not
3860 // if it's for local playback. Note also that we use the same delay between both tests
3861 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
Eric Laurent3b73df72014-03-11 09:06:29 -07003862 } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
Eric Laurente552edb2014-03-10 17:42:56 -07003863 // while media is playing (or has recently played), use the same device
3864 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
3865 } else {
3866 // when media is not playing anymore, fall back on the sonification behavior
3867 device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
3868 }
3869
3870 break;
3871
3872 case STRATEGY_DTMF:
3873 if (!isInCall()) {
3874 // when off call, DTMF strategy follows the same rules as MEDIA strategy
3875 device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
3876 break;
3877 }
3878 // when in call, DTMF and PHONE strategies follow the same rules
3879 // FALL THROUGH
3880
3881 case STRATEGY_PHONE:
Eric Laurentc2730ba2014-07-20 15:47:07 -07003882 // Force use of only devices on primary output if:
3883 // - in call AND
3884 // - cannot route from voice call RX OR
3885 // - audio HAL version is < 3.0 and TX device is on the primary HW module
3886 if (mPhoneState == AUDIO_MODE_IN_CALL) {
3887 audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
3888 sp<AudioOutputDescriptor> hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
3889 if (((mAvailableInputDevices.types() &
3890 AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
3891 (((txDevice & availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN) != 0) &&
Marco Nelissen961ec212014-08-25 15:58:39 -07003892 (hwOutputDesc->getAudioPort()->mModule->mHalVersion <
Eric Laurentc2730ba2014-07-20 15:47:07 -07003893 AUDIO_DEVICE_API_VERSION_3_0))) {
3894 availableOutputDeviceTypes = availablePrimaryOutputDevices();
3895 }
3896 }
Eric Laurente552edb2014-03-10 17:42:56 -07003897 // for phone strategy, we first consider the forced use and then the available devices by order
3898 // of priority
Eric Laurent3b73df72014-03-11 09:06:29 -07003899 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
3900 case AUDIO_POLICY_FORCE_BT_SCO:
Eric Laurente552edb2014-03-10 17:42:56 -07003901 if (!isInCall() || strategy != STRATEGY_DTMF) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003902 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
Eric Laurente552edb2014-03-10 17:42:56 -07003903 if (device) break;
3904 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003905 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003906 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003907 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
Eric Laurente552edb2014-03-10 17:42:56 -07003908 if (device) break;
3909 // if SCO device is requested but no SCO device is available, fall back to default case
3910 // FALL THROUGH
3911
3912 default: // FORCE_NONE
3913 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
Eric Laurent3a4311c2014-03-17 12:00:47 -07003914 if (!isInCall() &&
Eric Laurent3b73df72014-03-11 09:06:29 -07003915 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Eric Laurente552edb2014-03-10 17:42:56 -07003916 (getA2dpOutput() != 0) && !mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003917 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
Eric Laurente552edb2014-03-10 17:42:56 -07003918 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003919 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
Eric Laurente552edb2014-03-10 17:42:56 -07003920 if (device) break;
3921 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003922 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
Eric Laurente552edb2014-03-10 17:42:56 -07003923 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003924 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003925 if (device) break;
Eric Laurentc2730ba2014-07-20 15:47:07 -07003926 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
3927 if (device) break;
Eric Laurent3b73df72014-03-11 09:06:29 -07003928 if (mPhoneState != AUDIO_MODE_IN_CALL) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003929 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
Eric Laurente552edb2014-03-10 17:42:56 -07003930 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003931 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003932 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003933 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
Eric Laurente552edb2014-03-10 17:42:56 -07003934 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003935 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003936 if (device) break;
3937 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07003938 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
Eric Laurente552edb2014-03-10 17:42:56 -07003939 if (device) break;
Eric Laurent1c333e22014-05-20 10:48:17 -07003940 device = mDefaultOutputDevice->mDeviceType;
Eric Laurente552edb2014-03-10 17:42:56 -07003941 if (device == AUDIO_DEVICE_NONE) {
3942 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
3943 }
3944 break;
3945
Eric Laurent3b73df72014-03-11 09:06:29 -07003946 case AUDIO_POLICY_FORCE_SPEAKER:
Eric Laurente552edb2014-03-10 17:42:56 -07003947 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
3948 // A2DP speaker when forcing to speaker output
Eric Laurent3a4311c2014-03-17 12:00:47 -07003949 if (!isInCall() &&
Eric Laurent3b73df72014-03-11 09:06:29 -07003950 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Eric Laurente552edb2014-03-10 17:42:56 -07003951 (getA2dpOutput() != 0) && !mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003952 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
Eric Laurente552edb2014-03-10 17:42:56 -07003953 if (device) break;
3954 }
Eric Laurent3b73df72014-03-11 09:06:29 -07003955 if (mPhoneState != AUDIO_MODE_IN_CALL) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003956 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
Eric Laurente552edb2014-03-10 17:42:56 -07003957 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003958 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
Eric Laurente552edb2014-03-10 17:42:56 -07003959 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003960 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003961 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003962 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
Eric Laurente552edb2014-03-10 17:42:56 -07003963 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003964 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07003965 if (device) break;
3966 }
Jon Eklundac29afa2014-07-28 16:06:06 -05003967 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
3968 if (device) break;
Eric Laurent3a4311c2014-03-17 12:00:47 -07003969 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurente552edb2014-03-10 17:42:56 -07003970 if (device) break;
Eric Laurent1c333e22014-05-20 10:48:17 -07003971 device = mDefaultOutputDevice->mDeviceType;
Eric Laurente552edb2014-03-10 17:42:56 -07003972 if (device == AUDIO_DEVICE_NONE) {
3973 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
3974 }
3975 break;
3976 }
3977 break;
3978
3979 case STRATEGY_SONIFICATION:
3980
3981 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
3982 // handleIncallSonification().
3983 if (isInCall()) {
3984 device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
3985 break;
3986 }
3987 // FALL THROUGH
3988
3989 case STRATEGY_ENFORCED_AUDIBLE:
3990 // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
3991 // except:
3992 // - when in call where it doesn't default to STRATEGY_PHONE behavior
3993 // - in countries where not enforced in which case it follows STRATEGY_MEDIA
3994
3995 if ((strategy == STRATEGY_SONIFICATION) ||
Eric Laurent3b73df72014-03-11 09:06:29 -07003996 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07003997 device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurente552edb2014-03-10 17:42:56 -07003998 if (device == AUDIO_DEVICE_NONE) {
3999 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
4000 }
4001 }
4002 // The second device used for sonification is the same as the device used by media strategy
4003 // FALL THROUGH
4004
4005 case STRATEGY_MEDIA: {
4006 uint32_t device2 = AUDIO_DEVICE_NONE;
4007 if (strategy != STRATEGY_SONIFICATION) {
4008 // no sonification on remote submix (e.g. WFD)
Eric Laurent3a4311c2014-03-17 12:00:47 -07004009 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
Eric Laurente552edb2014-03-10 17:42:56 -07004010 }
4011 if ((device2 == AUDIO_DEVICE_NONE) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004012 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
Eric Laurente552edb2014-03-10 17:42:56 -07004013 (getA2dpOutput() != 0) && !mA2dpSuspended) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004014 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
Eric Laurente552edb2014-03-10 17:42:56 -07004015 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004016 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
Eric Laurente552edb2014-03-10 17:42:56 -07004017 }
4018 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004019 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
Eric Laurente552edb2014-03-10 17:42:56 -07004020 }
4021 }
4022 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004023 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
Eric Laurente552edb2014-03-10 17:42:56 -07004024 }
Jon Eklundac29afa2014-07-28 16:06:06 -05004025 if ((device2 == AUDIO_DEVICE_NONE)) {
4026 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_LINE;
4027 }
Eric Laurente552edb2014-03-10 17:42:56 -07004028 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004029 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07004030 }
4031 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004032 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
Eric Laurente552edb2014-03-10 17:42:56 -07004033 }
4034 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004035 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
Eric Laurente552edb2014-03-10 17:42:56 -07004036 }
4037 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004038 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07004039 }
4040 if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
4041 // no sonification on aux digital (e.g. HDMI)
Eric Laurent3a4311c2014-03-17 12:00:47 -07004042 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
Eric Laurente552edb2014-03-10 17:42:56 -07004043 }
4044 if ((device2 == AUDIO_DEVICE_NONE) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004045 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004046 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
Eric Laurente552edb2014-03-10 17:42:56 -07004047 }
4048 if (device2 == AUDIO_DEVICE_NONE) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07004049 device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurente552edb2014-03-10 17:42:56 -07004050 }
Jungshik Jang839e4f32014-06-26 17:23:40 +09004051 int device3 = AUDIO_DEVICE_NONE;
4052 if (strategy == STRATEGY_MEDIA) {
Jungshik Jang7b24ee32014-07-15 19:38:42 +09004053 // ARC, SPDIF and AUX_LINE can co-exist with others.
Jungshik Jang0c943092014-07-08 22:11:24 +09004054 device3 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_HDMI_ARC;
4055 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPDIF);
Jungshik Jang7b24ee32014-07-15 19:38:42 +09004056 device3 |= (availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_LINE);
Jungshik Jang839e4f32014-06-26 17:23:40 +09004057 }
Eric Laurente552edb2014-03-10 17:42:56 -07004058
Jungshik Jang839e4f32014-06-26 17:23:40 +09004059 device2 |= device3;
Eric Laurente552edb2014-03-10 17:42:56 -07004060 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
4061 // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
4062 device |= device2;
Jungshik Jang839e4f32014-06-26 17:23:40 +09004063
Jungshik Jang7b24ee32014-07-15 19:38:42 +09004064 // If hdmi system audio mode is on, remove speaker out of output list.
4065 if ((strategy == STRATEGY_MEDIA) &&
4066 (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
4067 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
4068 device &= ~AUDIO_DEVICE_OUT_SPEAKER;
4069 }
4070
Eric Laurente552edb2014-03-10 17:42:56 -07004071 if (device) break;
Eric Laurent1c333e22014-05-20 10:48:17 -07004072 device = mDefaultOutputDevice->mDeviceType;
Eric Laurente552edb2014-03-10 17:42:56 -07004073 if (device == AUDIO_DEVICE_NONE) {
4074 ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
4075 }
4076 } break;
4077
4078 default:
4079 ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
4080 break;
4081 }
4082
4083 ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
4084 return device;
4085}
4086
Eric Laurente0720872014-03-11 09:30:41 -07004087void AudioPolicyManager::updateDevicesAndOutputs()
Eric Laurente552edb2014-03-10 17:42:56 -07004088{
4089 for (int i = 0; i < NUM_STRATEGIES; i++) {
4090 mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4091 }
4092 mPreviousOutputs = mOutputs;
4093}
4094
Eric Laurent1f2f2232014-06-02 12:01:23 -07004095uint32_t AudioPolicyManager::checkDeviceMuteStrategies(sp<AudioOutputDescriptor> outputDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004096 audio_devices_t prevDevice,
4097 uint32_t delayMs)
4098{
4099 // mute/unmute strategies using an incompatible device combination
4100 // if muting, wait for the audio in pcm buffer to be drained before proceeding
4101 // if unmuting, unmute only after the specified delay
4102 if (outputDesc->isDuplicated()) {
4103 return 0;
4104 }
4105
4106 uint32_t muteWaitMs = 0;
4107 audio_devices_t device = outputDesc->device();
Eric Laurent3b73df72014-03-11 09:06:29 -07004108 bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
Eric Laurente552edb2014-03-10 17:42:56 -07004109
4110 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4111 audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
4112 bool mute = shouldMute && (curDevice & device) && (curDevice != device);
4113 bool doMute = false;
4114
4115 if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
4116 doMute = true;
4117 outputDesc->mStrategyMutedByDevice[i] = true;
4118 } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
4119 doMute = true;
4120 outputDesc->mStrategyMutedByDevice[i] = false;
4121 }
Eric Laurent99401132014-05-07 19:48:15 -07004122 if (doMute) {
Eric Laurente552edb2014-03-10 17:42:56 -07004123 for (size_t j = 0; j < mOutputs.size(); j++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004124 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(j);
Eric Laurente552edb2014-03-10 17:42:56 -07004125 // skip output if it does not share any device with current output
4126 if ((desc->supportedDevices() & outputDesc->supportedDevices())
4127 == AUDIO_DEVICE_NONE) {
4128 continue;
4129 }
4130 audio_io_handle_t curOutput = mOutputs.keyAt(j);
4131 ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
4132 mute ? "muting" : "unmuting", i, curDevice, curOutput);
4133 setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
4134 if (desc->isStrategyActive((routing_strategy)i)) {
Eric Laurent99401132014-05-07 19:48:15 -07004135 if (mute) {
4136 // FIXME: should not need to double latency if volume could be applied
4137 // immediately by the audioflinger mixer. We must account for the delay
4138 // between now and the next time the audioflinger thread for this output
4139 // will process a buffer (which corresponds to one buffer size,
4140 // usually 1/2 or 1/4 of the latency).
4141 if (muteWaitMs < desc->latency() * 2) {
4142 muteWaitMs = desc->latency() * 2;
Eric Laurente552edb2014-03-10 17:42:56 -07004143 }
4144 }
4145 }
4146 }
4147 }
4148 }
4149
Eric Laurent99401132014-05-07 19:48:15 -07004150 // temporary mute output if device selection changes to avoid volume bursts due to
4151 // different per device volumes
4152 if (outputDesc->isActive() && (device != prevDevice)) {
4153 if (muteWaitMs < outputDesc->latency() * 2) {
4154 muteWaitMs = outputDesc->latency() * 2;
4155 }
4156 for (size_t i = 0; i < NUM_STRATEGIES; i++) {
4157 if (outputDesc->isStrategyActive((routing_strategy)i)) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004158 setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle);
Eric Laurent99401132014-05-07 19:48:15 -07004159 // do tempMute unmute after twice the mute wait time
Eric Laurent1c333e22014-05-20 10:48:17 -07004160 setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle,
Eric Laurent99401132014-05-07 19:48:15 -07004161 muteWaitMs *2, device);
4162 }
4163 }
4164 }
4165
Eric Laurente552edb2014-03-10 17:42:56 -07004166 // wait for the PCM output buffers to empty before proceeding with the rest of the command
4167 if (muteWaitMs > delayMs) {
4168 muteWaitMs -= delayMs;
4169 usleep(muteWaitMs * 1000);
4170 return muteWaitMs;
4171 }
4172 return 0;
4173}
4174
Eric Laurente0720872014-03-11 09:30:41 -07004175uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
Eric Laurente552edb2014-03-10 17:42:56 -07004176 audio_devices_t device,
4177 bool force,
Eric Laurent6a94d692014-05-20 11:18:06 -07004178 int delayMs,
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004179 audio_patch_handle_t *patchHandle,
4180 const char* address)
Eric Laurente552edb2014-03-10 17:42:56 -07004181{
4182 ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
Eric Laurent1f2f2232014-06-02 12:01:23 -07004183 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004184 AudioParameter param;
4185 uint32_t muteWaitMs;
4186
4187 if (outputDesc->isDuplicated()) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004188 muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs);
4189 muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004190 return muteWaitMs;
4191 }
4192 // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
4193 // output profile
4194 if ((device != AUDIO_DEVICE_NONE) &&
Eric Laurent3a4311c2014-03-17 12:00:47 -07004195 ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004196 return 0;
4197 }
4198
4199 // filter devices according to output selected
Eric Laurent3a4311c2014-03-17 12:00:47 -07004200 device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
Eric Laurente552edb2014-03-10 17:42:56 -07004201
4202 audio_devices_t prevDevice = outputDesc->mDevice;
4203
4204 ALOGV("setOutputDevice() prevDevice %04x", prevDevice);
4205
4206 if (device != AUDIO_DEVICE_NONE) {
4207 outputDesc->mDevice = device;
4208 }
4209 muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
4210
4211 // Do not change the routing if:
4212 // - the requested device is AUDIO_DEVICE_NONE
4213 // - the requested device is the same as current device and force is not specified.
4214 // Doing this check here allows the caller to call setOutputDevice() without conditions
4215 if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) {
4216 ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
4217 return muteWaitMs;
4218 }
4219
4220 ALOGV("setOutputDevice() changing device");
Eric Laurent1c333e22014-05-20 10:48:17 -07004221
Eric Laurente552edb2014-03-10 17:42:56 -07004222 // do the routing
Eric Laurent1c333e22014-05-20 10:48:17 -07004223 if (device == AUDIO_DEVICE_NONE) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004224 resetOutputDevice(output, delayMs, NULL);
Eric Laurent1c333e22014-05-20 10:48:17 -07004225 } else {
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004226 DeviceVector deviceList = (address == NULL) ?
4227 mAvailableOutputDevices.getDevicesFromType(device)
4228 : mAvailableOutputDevices.getDevicesFromTypeAddr(device, String8(address));
Eric Laurent1c333e22014-05-20 10:48:17 -07004229 if (!deviceList.isEmpty()) {
4230 struct audio_patch patch;
4231 outputDesc->toAudioPortConfig(&patch.sources[0]);
4232 patch.num_sources = 1;
4233 patch.num_sinks = 0;
4234 for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
4235 deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
Eric Laurent1c333e22014-05-20 10:48:17 -07004236 patch.num_sinks++;
4237 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004238 ssize_t index;
4239 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
4240 index = mAudioPatches.indexOfKey(*patchHandle);
4241 } else {
4242 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
4243 }
4244 sp< AudioPatch> patchDesc;
4245 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
4246 if (index >= 0) {
4247 patchDesc = mAudioPatches.valueAt(index);
4248 afPatchHandle = patchDesc->mAfPatchHandle;
4249 }
4250
Eric Laurent1c333e22014-05-20 10:48:17 -07004251 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07004252 &afPatchHandle,
4253 delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07004254 ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
4255 "num_sources %d num_sinks %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004256 status, afPatchHandle, patch.num_sources, patch.num_sinks);
Eric Laurent1c333e22014-05-20 10:48:17 -07004257 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004258 if (index < 0) {
4259 patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
4260 &patch, mUidCached);
4261 addAudioPatch(patchDesc->mHandle, patchDesc);
4262 } else {
4263 patchDesc->mPatch = patch;
4264 }
4265 patchDesc->mAfPatchHandle = afPatchHandle;
4266 patchDesc->mUid = mUidCached;
4267 if (patchHandle) {
4268 *patchHandle = patchDesc->mHandle;
4269 }
4270 outputDesc->mPatchHandle = patchDesc->mHandle;
4271 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004272 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004273 }
4274 }
4275 }
Eric Laurente552edb2014-03-10 17:42:56 -07004276
4277 // update stream volumes according to new device
4278 applyStreamVolumes(output, device, delayMs);
4279
4280 return muteWaitMs;
4281}
4282
Eric Laurent1c333e22014-05-20 10:48:17 -07004283status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output,
Eric Laurent6a94d692014-05-20 11:18:06 -07004284 int delayMs,
4285 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004286{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004287 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurent6a94d692014-05-20 11:18:06 -07004288 ssize_t index;
4289 if (patchHandle) {
4290 index = mAudioPatches.indexOfKey(*patchHandle);
4291 } else {
4292 index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
4293 }
4294 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004295 return INVALID_OPERATION;
4296 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004297 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4298 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
Eric Laurent1c333e22014-05-20 10:48:17 -07004299 ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
4300 outputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004301 removeAudioPatch(patchDesc->mHandle);
4302 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004303 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004304 return status;
4305}
4306
4307status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
4308 audio_devices_t device,
Eric Laurent6a94d692014-05-20 11:18:06 -07004309 bool force,
4310 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004311{
4312 status_t status = NO_ERROR;
4313
Eric Laurent1f2f2232014-06-02 12:01:23 -07004314 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent1c333e22014-05-20 10:48:17 -07004315 if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
4316 inputDesc->mDevice = device;
4317
4318 DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
4319 if (!deviceList.isEmpty()) {
4320 struct audio_patch patch;
4321 inputDesc->toAudioPortConfig(&patch.sinks[0]);
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004322 // AUDIO_SOURCE_HOTWORD is for internal use only:
4323 // handled as AUDIO_SOURCE_VOICE_RECOGNITION by the audio HAL
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07004324 if (patch.sinks[0].ext.mix.usecase.source == AUDIO_SOURCE_HOTWORD &&
4325 !inputDesc->mIsSoundTrigger) {
Eric Laurentdaf92cc2014-07-22 15:36:10 -07004326 patch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_VOICE_RECOGNITION;
4327 }
Eric Laurent1c333e22014-05-20 10:48:17 -07004328 patch.num_sinks = 1;
4329 //only one input device for now
4330 deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
Eric Laurent1c333e22014-05-20 10:48:17 -07004331 patch.num_sources = 1;
Eric Laurent6a94d692014-05-20 11:18:06 -07004332 ssize_t index;
4333 if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
4334 index = mAudioPatches.indexOfKey(*patchHandle);
4335 } else {
4336 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4337 }
4338 sp< AudioPatch> patchDesc;
4339 audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
4340 if (index >= 0) {
4341 patchDesc = mAudioPatches.valueAt(index);
4342 afPatchHandle = patchDesc->mAfPatchHandle;
4343 }
4344
Eric Laurent1c333e22014-05-20 10:48:17 -07004345 status_t status = mpClientInterface->createAudioPatch(&patch,
Eric Laurent6a94d692014-05-20 11:18:06 -07004346 &afPatchHandle,
Eric Laurent1c333e22014-05-20 10:48:17 -07004347 0);
4348 ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
Eric Laurent6a94d692014-05-20 11:18:06 -07004349 status, afPatchHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -07004350 if (status == NO_ERROR) {
Eric Laurent6a94d692014-05-20 11:18:06 -07004351 if (index < 0) {
4352 patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
4353 &patch, mUidCached);
4354 addAudioPatch(patchDesc->mHandle, patchDesc);
4355 } else {
4356 patchDesc->mPatch = patch;
4357 }
4358 patchDesc->mAfPatchHandle = afPatchHandle;
4359 patchDesc->mUid = mUidCached;
4360 if (patchHandle) {
4361 *patchHandle = patchDesc->mHandle;
4362 }
4363 inputDesc->mPatchHandle = patchDesc->mHandle;
4364 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004365 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004366 }
4367 }
4368 }
4369 return status;
4370}
4371
Eric Laurent6a94d692014-05-20 11:18:06 -07004372status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
4373 audio_patch_handle_t *patchHandle)
Eric Laurent1c333e22014-05-20 10:48:17 -07004374{
Eric Laurent1f2f2232014-06-02 12:01:23 -07004375 sp<AudioInputDescriptor> inputDesc = mInputs.valueFor(input);
Eric Laurent6a94d692014-05-20 11:18:06 -07004376 ssize_t index;
4377 if (patchHandle) {
4378 index = mAudioPatches.indexOfKey(*patchHandle);
4379 } else {
4380 index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
4381 }
4382 if (index < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07004383 return INVALID_OPERATION;
4384 }
Eric Laurent6a94d692014-05-20 11:18:06 -07004385 sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
4386 status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
Eric Laurent1c333e22014-05-20 10:48:17 -07004387 ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
4388 inputDesc->mPatchHandle = 0;
Eric Laurent6a94d692014-05-20 11:18:06 -07004389 removeAudioPatch(patchDesc->mHandle);
4390 nextAudioPortGeneration();
Eric Laurentb52c1522014-05-20 11:27:36 -07004391 mpClientInterface->onAudioPatchListUpdate();
Eric Laurent1c333e22014-05-20 10:48:17 -07004392 return status;
4393}
4394
4395sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
Glenn Kastencbd48022014-07-24 13:46:44 -07004396 uint32_t& samplingRate,
Eric Laurente552edb2014-03-10 17:42:56 -07004397 audio_format_t format,
Glenn Kasten6a8ab052014-07-24 14:08:35 -07004398 audio_channel_mask_t channelMask,
Glenn Kastencbd48022014-07-24 13:46:44 -07004399 audio_input_flags_t flags)
Eric Laurente552edb2014-03-10 17:42:56 -07004400{
4401 // Choose an input profile based on the requested capture parameters: select the first available
4402 // profile supporting all requested parameters.
4403
4404 for (size_t i = 0; i < mHwModules.size(); i++)
4405 {
4406 if (mHwModules[i]->mHandle == 0) {
4407 continue;
4408 }
4409 for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
4410 {
Eric Laurent1c333e22014-05-20 10:48:17 -07004411 sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
Eric Laurentd4692962014-05-05 18:13:44 -07004412 // profile->log();
Glenn Kastencbd48022014-07-24 13:46:44 -07004413 if (profile->isCompatibleProfile(device, samplingRate,
4414 &samplingRate /*updatedSamplingRate*/,
4415 format, channelMask, (audio_output_flags_t) flags)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004416 return profile;
4417 }
4418 }
4419 }
4420 return NULL;
4421}
4422
Eric Laurente0720872014-03-11 09:30:41 -07004423audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
Eric Laurente552edb2014-03-10 17:42:56 -07004424{
4425 uint32_t device = AUDIO_DEVICE_NONE;
Eric Laurent3a4311c2014-03-17 12:00:47 -07004426 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
4427 ~AUDIO_DEVICE_BIT_IN;
Eric Laurente552edb2014-03-10 17:42:56 -07004428 switch (inputSource) {
4429 case AUDIO_SOURCE_VOICE_UPLINK:
Eric Laurent3a4311c2014-03-17 12:00:47 -07004430 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
Eric Laurente552edb2014-03-10 17:42:56 -07004431 device = AUDIO_DEVICE_IN_VOICE_CALL;
4432 break;
4433 }
Eric Laurentc2730ba2014-07-20 15:47:07 -07004434 break;
Eric Laurente552edb2014-03-10 17:42:56 -07004435
4436 case AUDIO_SOURCE_DEFAULT:
4437 case AUDIO_SOURCE_MIC:
Mike Lockwood41b0e242014-05-13 15:23:35 -07004438 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
4439 device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
Eric Laurentc2730ba2014-07-20 15:47:07 -07004440 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
4441 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
4442 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
4443 device = AUDIO_DEVICE_IN_USB_DEVICE;
4444 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
4445 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Mike Lockwood41b0e242014-05-13 15:23:35 -07004446 }
Eric Laurentc2730ba2014-07-20 15:47:07 -07004447 break;
4448
4449 case AUDIO_SOURCE_VOICE_COMMUNICATION:
4450 // Allow only use of devices on primary input if in call and HAL does not support routing
4451 // to voice call path.
4452 if ((mPhoneState == AUDIO_MODE_IN_CALL) &&
4453 (mAvailableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
4454 availableDeviceTypes = availablePrimaryInputDevices() & ~AUDIO_DEVICE_BIT_IN;
4455 }
4456
4457 switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
4458 case AUDIO_POLICY_FORCE_BT_SCO:
4459 // if SCO device is requested but no SCO device is available, fall back to default case
4460 if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
4461 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
4462 break;
4463 }
4464 // FALL THROUGH
4465
4466 default: // FORCE_NONE
4467 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
4468 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
4469 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
4470 device = AUDIO_DEVICE_IN_USB_DEVICE;
4471 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
4472 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
4473 }
4474 break;
4475
4476 case AUDIO_POLICY_FORCE_SPEAKER:
4477 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
4478 device = AUDIO_DEVICE_IN_BACK_MIC;
4479 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
4480 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
4481 }
4482 break;
4483 }
4484 break;
Mike Lockwood41b0e242014-05-13 15:23:35 -07004485
Eric Laurente552edb2014-03-10 17:42:56 -07004486 case AUDIO_SOURCE_VOICE_RECOGNITION:
4487 case AUDIO_SOURCE_HOTWORD:
Eric Laurent3b73df72014-03-11 09:06:29 -07004488 if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
Eric Laurent3a4311c2014-03-17 12:00:47 -07004489 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
Eric Laurente552edb2014-03-10 17:42:56 -07004490 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
Eric Laurent3a4311c2014-03-17 12:00:47 -07004491 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
Eric Laurente552edb2014-03-10 17:42:56 -07004492 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Eric Laurentd4692962014-05-05 18:13:44 -07004493 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
4494 device = AUDIO_DEVICE_IN_USB_DEVICE;
Eric Laurent3a4311c2014-03-17 12:00:47 -07004495 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Eric Laurente552edb2014-03-10 17:42:56 -07004496 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
4497 }
4498 break;
4499 case AUDIO_SOURCE_CAMCORDER:
Eric Laurent3a4311c2014-03-17 12:00:47 -07004500 if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
Eric Laurente552edb2014-03-10 17:42:56 -07004501 device = AUDIO_DEVICE_IN_BACK_MIC;
Eric Laurent3a4311c2014-03-17 12:00:47 -07004502 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
Eric Laurente552edb2014-03-10 17:42:56 -07004503 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
4504 }
4505 break;
4506 case AUDIO_SOURCE_VOICE_DOWNLINK:
4507 case AUDIO_SOURCE_VOICE_CALL:
Eric Laurent3a4311c2014-03-17 12:00:47 -07004508 if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
Eric Laurente552edb2014-03-10 17:42:56 -07004509 device = AUDIO_DEVICE_IN_VOICE_CALL;
4510 }
4511 break;
4512 case AUDIO_SOURCE_REMOTE_SUBMIX:
Eric Laurent3a4311c2014-03-17 12:00:47 -07004513 if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
Eric Laurente552edb2014-03-10 17:42:56 -07004514 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
4515 }
4516 break;
4517 default:
4518 ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
4519 break;
4520 }
4521 ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
4522 return device;
4523}
4524
Eric Laurente0720872014-03-11 09:30:41 -07004525bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004526{
4527 if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
4528 device &= ~AUDIO_DEVICE_BIT_IN;
4529 if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
4530 return true;
4531 }
4532 return false;
4533}
4534
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07004535bool AudioPolicyManager::deviceDistinguishesOnAddress(audio_devices_t device) {
4536 return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL) != 0);
4537}
4538
Eric Laurente0720872014-03-11 09:30:41 -07004539audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs)
Eric Laurente552edb2014-03-10 17:42:56 -07004540{
4541 for (size_t i = 0; i < mInputs.size(); i++) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07004542 const sp<AudioInputDescriptor> input_descriptor = mInputs.valueAt(i);
Eric Laurente552edb2014-03-10 17:42:56 -07004543 if ((input_descriptor->mRefCount > 0)
4544 && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) {
4545 return mInputs.keyAt(i);
4546 }
4547 }
4548 return 0;
4549}
4550
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07004551uint32_t AudioPolicyManager::activeInputsCount() const
4552{
4553 uint32_t count = 0;
4554 for (size_t i = 0; i < mInputs.size(); i++) {
4555 const sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
4556 if (desc->mRefCount > 0) {
4557 return count++;
4558 }
4559 }
4560 return count;
4561}
4562
Eric Laurente552edb2014-03-10 17:42:56 -07004563
Eric Laurente0720872014-03-11 09:30:41 -07004564audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004565{
4566 if (device == AUDIO_DEVICE_NONE) {
4567 // this happens when forcing a route update and no track is active on an output.
4568 // In this case the returned category is not important.
4569 device = AUDIO_DEVICE_OUT_SPEAKER;
Eric Laurent3b73df72014-03-11 09:06:29 -07004570 } else if (popcount(device) > 1) {
Eric Laurente552edb2014-03-10 17:42:56 -07004571 // Multiple device selection is either:
4572 // - speaker + one other device: give priority to speaker in this case.
4573 // - one A2DP device + another device: happens with duplicated output. In this case
4574 // retain the device on the A2DP output as the other must not correspond to an active
4575 // selection if not the speaker.
4576 if (device & AUDIO_DEVICE_OUT_SPEAKER) {
4577 device = AUDIO_DEVICE_OUT_SPEAKER;
4578 } else {
4579 device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
4580 }
4581 }
4582
Eric Laurent3b73df72014-03-11 09:06:29 -07004583 ALOGW_IF(popcount(device) != 1,
Eric Laurente552edb2014-03-10 17:42:56 -07004584 "getDeviceForVolume() invalid device combination: %08x",
4585 device);
4586
4587 return device;
4588}
4589
Eric Laurente0720872014-03-11 09:30:41 -07004590AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07004591{
4592 switch(getDeviceForVolume(device)) {
4593 case AUDIO_DEVICE_OUT_EARPIECE:
4594 return DEVICE_CATEGORY_EARPIECE;
4595 case AUDIO_DEVICE_OUT_WIRED_HEADSET:
4596 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
4597 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
4598 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
4599 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
4600 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
4601 return DEVICE_CATEGORY_HEADSET;
Jon Eklundac29afa2014-07-28 16:06:06 -05004602 case AUDIO_DEVICE_OUT_LINE:
4603 case AUDIO_DEVICE_OUT_AUX_DIGITAL:
4604 /*USB? Remote submix?*/
4605 return DEVICE_CATEGORY_EXT_MEDIA;
Eric Laurente552edb2014-03-10 17:42:56 -07004606 case AUDIO_DEVICE_OUT_SPEAKER:
4607 case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
4608 case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
Eric Laurente552edb2014-03-10 17:42:56 -07004609 case AUDIO_DEVICE_OUT_USB_ACCESSORY:
4610 case AUDIO_DEVICE_OUT_USB_DEVICE:
4611 case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
4612 default:
4613 return DEVICE_CATEGORY_SPEAKER;
4614 }
4615}
4616
Eric Laurente0720872014-03-11 09:30:41 -07004617float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
Eric Laurente552edb2014-03-10 17:42:56 -07004618 int indexInUi)
4619{
4620 device_category deviceCategory = getDeviceCategory(device);
4621 const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
4622
4623 // the volume index in the UI is relative to the min and max volume indices for this stream type
4624 int nbSteps = 1 + curve[VOLMAX].mIndex -
4625 curve[VOLMIN].mIndex;
4626 int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
4627 (streamDesc.mIndexMax - streamDesc.mIndexMin);
4628
4629 // find what part of the curve this index volume belongs to, or if it's out of bounds
4630 int segment = 0;
4631 if (volIdx < curve[VOLMIN].mIndex) { // out of bounds
4632 return 0.0f;
4633 } else if (volIdx < curve[VOLKNEE1].mIndex) {
4634 segment = 0;
4635 } else if (volIdx < curve[VOLKNEE2].mIndex) {
4636 segment = 1;
4637 } else if (volIdx <= curve[VOLMAX].mIndex) {
4638 segment = 2;
4639 } else { // out of bounds
4640 return 1.0f;
4641 }
4642
4643 // linear interpolation in the attenuation table in dB
4644 float decibels = curve[segment].mDBAttenuation +
4645 ((float)(volIdx - curve[segment].mIndex)) *
4646 ( (curve[segment+1].mDBAttenuation -
4647 curve[segment].mDBAttenuation) /
4648 ((float)(curve[segment+1].mIndex -
4649 curve[segment].mIndex)) );
4650
4651 float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
4652
4653 ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
4654 curve[segment].mIndex, volIdx,
4655 curve[segment+1].mIndex,
4656 curve[segment].mDBAttenuation,
4657 decibels,
4658 curve[segment+1].mDBAttenuation,
4659 amplification);
4660
4661 return amplification;
4662}
4663
Eric Laurente0720872014-03-11 09:30:41 -07004664const AudioPolicyManager::VolumeCurvePoint
4665 AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004666 {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
4667};
4668
Eric Laurente0720872014-03-11 09:30:41 -07004669const AudioPolicyManager::VolumeCurvePoint
4670 AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004671 {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
4672};
4673
Eric Laurente0720872014-03-11 09:30:41 -07004674const AudioPolicyManager::VolumeCurvePoint
Jon Eklundac29afa2014-07-28 16:06:06 -05004675 AudioPolicyManager::sExtMediaSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
4676 {1, -58.0f}, {20, -40.0f}, {60, -21.0f}, {100, -10.0f}
4677};
4678
4679const AudioPolicyManager::VolumeCurvePoint
Eric Laurente0720872014-03-11 09:30:41 -07004680 AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004681 {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
4682};
4683
Eric Laurente0720872014-03-11 09:30:41 -07004684const AudioPolicyManager::VolumeCurvePoint
Jean-Michel Triviccd8e4a2014-06-05 15:33:20 -07004685 AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
Jean-Michel Trivi98c60432014-07-09 08:51:34 -07004686 {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
Jean-Michel Triviccd8e4a2014-06-05 15:33:20 -07004687};
4688
4689const AudioPolicyManager::VolumeCurvePoint
Eric Laurente0720872014-03-11 09:30:41 -07004690 AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004691 {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
4692};
4693
Eric Laurente0720872014-03-11 09:30:41 -07004694const AudioPolicyManager::VolumeCurvePoint
4695 AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004696 {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
4697};
4698
4699// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
4700// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
4701// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
4702// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
4703
Eric Laurente0720872014-03-11 09:30:41 -07004704const AudioPolicyManager::VolumeCurvePoint
4705 AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004706 {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
4707};
4708
Eric Laurente0720872014-03-11 09:30:41 -07004709const AudioPolicyManager::VolumeCurvePoint
4710 AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004711 {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
4712};
4713
Eric Laurente0720872014-03-11 09:30:41 -07004714const AudioPolicyManager::VolumeCurvePoint
4715 AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004716 {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
4717};
4718
Eric Laurente0720872014-03-11 09:30:41 -07004719const AudioPolicyManager::VolumeCurvePoint
4720 AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004721 {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
4722};
4723
Eric Laurente0720872014-03-11 09:30:41 -07004724const AudioPolicyManager::VolumeCurvePoint
4725 AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004726 {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
4727};
4728
Eric Laurente0720872014-03-11 09:30:41 -07004729const AudioPolicyManager::VolumeCurvePoint
4730 *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
4731 [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
Eric Laurente552edb2014-03-10 17:42:56 -07004732 { // AUDIO_STREAM_VOICE_CALL
4733 sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
4734 sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004735 sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4736 sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004737 },
4738 { // AUDIO_STREAM_SYSTEM
4739 sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
4740 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004741 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4742 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004743 },
4744 { // AUDIO_STREAM_RING
4745 sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
4746 sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004747 sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4748 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004749 },
4750 { // AUDIO_STREAM_MUSIC
4751 sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
4752 sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004753 sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4754 sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004755 },
4756 { // AUDIO_STREAM_ALARM
4757 sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
4758 sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004759 sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4760 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004761 },
4762 { // AUDIO_STREAM_NOTIFICATION
4763 sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
4764 sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004765 sDefaultVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4766 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004767 },
4768 { // AUDIO_STREAM_BLUETOOTH_SCO
4769 sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
4770 sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004771 sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4772 sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004773 },
4774 { // AUDIO_STREAM_ENFORCED_AUDIBLE
4775 sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
4776 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004777 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4778 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004779 },
4780 { // AUDIO_STREAM_DTMF
4781 sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
4782 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004783 sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4784 sExtMediaSystemVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004785 },
4786 { // AUDIO_STREAM_TTS
4787 sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
4788 sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
Jon Eklundac29afa2014-07-28 16:06:06 -05004789 sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
4790 sDefaultMediaVolumeCurve // DEVICE_CATEGORY_EXT_MEDIA
Eric Laurente552edb2014-03-10 17:42:56 -07004791 },
4792};
4793
Eric Laurente0720872014-03-11 09:30:41 -07004794void AudioPolicyManager::initializeVolumeCurves()
Eric Laurente552edb2014-03-10 17:42:56 -07004795{
4796 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
4797 for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
4798 mStreams[i].mVolumeCurve[j] =
4799 sVolumeProfiles[i][j];
4800 }
4801 }
4802
4803 // Check availability of DRC on speaker path: if available, override some of the speaker curves
4804 if (mSpeakerDrcEnabled) {
4805 mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
4806 sDefaultSystemVolumeCurveDrc;
4807 mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
4808 sSpeakerSonificationVolumeCurveDrc;
4809 mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
4810 sSpeakerSonificationVolumeCurveDrc;
4811 mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
4812 sSpeakerSonificationVolumeCurveDrc;
Jean-Michel Triviccd8e4a2014-06-05 15:33:20 -07004813 mStreams[AUDIO_STREAM_MUSIC].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
4814 sSpeakerMediaVolumeCurveDrc;
Eric Laurente552edb2014-03-10 17:42:56 -07004815 }
4816}
4817
Eric Laurente0720872014-03-11 09:30:41 -07004818float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07004819 int index,
4820 audio_io_handle_t output,
4821 audio_devices_t device)
4822{
4823 float volume = 1.0;
Eric Laurent1f2f2232014-06-02 12:01:23 -07004824 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004825 StreamDescriptor &streamDesc = mStreams[stream];
4826
4827 if (device == AUDIO_DEVICE_NONE) {
4828 device = outputDesc->device();
4829 }
4830
Eric Laurente552edb2014-03-10 17:42:56 -07004831 volume = volIndexToAmpl(device, streamDesc, index);
4832
4833 // if a headset is connected, apply the following rules to ring tones and notifications
4834 // to avoid sound level bursts in user's ears:
4835 // - always attenuate ring tones and notifications volume by 6dB
4836 // - if music is playing, always limit the volume to current music volume,
4837 // with a minimum threshold at -36dB so that notification is always perceived.
Eric Laurent3b73df72014-03-11 09:06:29 -07004838 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07004839 if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
4840 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
4841 AUDIO_DEVICE_OUT_WIRED_HEADSET |
4842 AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
4843 ((stream_strategy == STRATEGY_SONIFICATION)
4844 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
Eric Laurent3b73df72014-03-11 09:06:29 -07004845 || (stream == AUDIO_STREAM_SYSTEM)
Eric Laurente552edb2014-03-10 17:42:56 -07004846 || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004847 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
Eric Laurente552edb2014-03-10 17:42:56 -07004848 streamDesc.mCanBeMuted) {
4849 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
4850 // when the phone is ringing we must consider that music could have been paused just before
4851 // by the music application and behave as if music was active if the last music track was
4852 // just stopped
Eric Laurent3b73df72014-03-11 09:06:29 -07004853 if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
Eric Laurente552edb2014-03-10 17:42:56 -07004854 mLimitRingtoneVolume) {
4855 audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
Eric Laurent3b73df72014-03-11 09:06:29 -07004856 float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
4857 mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
Eric Laurente552edb2014-03-10 17:42:56 -07004858 output,
4859 musicDevice);
4860 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
4861 musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
4862 if (volume > minVol) {
4863 volume = minVol;
4864 ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
4865 }
4866 }
4867 }
4868
4869 return volume;
4870}
4871
Eric Laurente0720872014-03-11 09:30:41 -07004872status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07004873 int index,
4874 audio_io_handle_t output,
4875 audio_devices_t device,
4876 int delayMs,
4877 bool force)
4878{
4879
4880 // do not change actual stream volume if the stream is muted
4881 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
4882 ALOGVV("checkAndSetVolume() stream %d muted count %d",
4883 stream, mOutputs.valueFor(output)->mMuteCount[stream]);
4884 return NO_ERROR;
4885 }
4886
4887 // do not change in call volume if bluetooth is connected and vice versa
Eric Laurent3b73df72014-03-11 09:06:29 -07004888 if ((stream == AUDIO_STREAM_VOICE_CALL &&
4889 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
4890 (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
4891 mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
Eric Laurente552edb2014-03-10 17:42:56 -07004892 ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
Eric Laurent3b73df72014-03-11 09:06:29 -07004893 stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
Eric Laurente552edb2014-03-10 17:42:56 -07004894 return INVALID_OPERATION;
4895 }
4896
4897 float volume = computeVolume(stream, index, output, device);
4898 // We actually change the volume if:
4899 // - the float value returned by computeVolume() changed
4900 // - the force flag is set
4901 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
4902 force) {
4903 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
4904 ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
4905 // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
4906 // enabled
Eric Laurent3b73df72014-03-11 09:06:29 -07004907 if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
4908 mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004909 }
Eric Laurent3b73df72014-03-11 09:06:29 -07004910 mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
Eric Laurente552edb2014-03-10 17:42:56 -07004911 }
4912
Eric Laurent3b73df72014-03-11 09:06:29 -07004913 if (stream == AUDIO_STREAM_VOICE_CALL ||
4914 stream == AUDIO_STREAM_BLUETOOTH_SCO) {
Eric Laurente552edb2014-03-10 17:42:56 -07004915 float voiceVolume;
4916 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
Eric Laurent3b73df72014-03-11 09:06:29 -07004917 if (stream == AUDIO_STREAM_VOICE_CALL) {
Eric Laurente552edb2014-03-10 17:42:56 -07004918 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
4919 } else {
4920 voiceVolume = 1.0;
4921 }
4922
4923 if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
4924 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
4925 mLastVoiceVolume = voiceVolume;
4926 }
4927 }
4928
4929 return NO_ERROR;
4930}
4931
Eric Laurente0720872014-03-11 09:30:41 -07004932void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
Eric Laurente552edb2014-03-10 17:42:56 -07004933 audio_devices_t device,
4934 int delayMs,
4935 bool force)
4936{
4937 ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
4938
Eric Laurent3b73df72014-03-11 09:06:29 -07004939 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
4940 checkAndSetVolume((audio_stream_type_t)stream,
Eric Laurente552edb2014-03-10 17:42:56 -07004941 mStreams[stream].getVolumeIndex(device),
4942 output,
4943 device,
4944 delayMs,
4945 force);
4946 }
4947}
4948
Eric Laurente0720872014-03-11 09:30:41 -07004949void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
Eric Laurente552edb2014-03-10 17:42:56 -07004950 bool on,
4951 audio_io_handle_t output,
4952 int delayMs,
4953 audio_devices_t device)
4954{
4955 ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
Eric Laurent3b73df72014-03-11 09:06:29 -07004956 for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
4957 if (getStrategy((audio_stream_type_t)stream) == strategy) {
4958 setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
Eric Laurente552edb2014-03-10 17:42:56 -07004959 }
4960 }
4961}
4962
Eric Laurente0720872014-03-11 09:30:41 -07004963void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07004964 bool on,
4965 audio_io_handle_t output,
4966 int delayMs,
4967 audio_devices_t device)
4968{
4969 StreamDescriptor &streamDesc = mStreams[stream];
Eric Laurent1f2f2232014-06-02 12:01:23 -07004970 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
Eric Laurente552edb2014-03-10 17:42:56 -07004971 if (device == AUDIO_DEVICE_NONE) {
4972 device = outputDesc->device();
4973 }
4974
4975 ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
4976 stream, on, output, outputDesc->mMuteCount[stream], device);
4977
4978 if (on) {
4979 if (outputDesc->mMuteCount[stream] == 0) {
4980 if (streamDesc.mCanBeMuted &&
Eric Laurent3b73df72014-03-11 09:06:29 -07004981 ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
4982 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) {
Eric Laurente552edb2014-03-10 17:42:56 -07004983 checkAndSetVolume(stream, 0, output, device, delayMs);
4984 }
4985 }
4986 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
4987 outputDesc->mMuteCount[stream]++;
4988 } else {
4989 if (outputDesc->mMuteCount[stream] == 0) {
4990 ALOGV("setStreamMute() unmuting non muted stream!");
4991 return;
4992 }
4993 if (--outputDesc->mMuteCount[stream] == 0) {
4994 checkAndSetVolume(stream,
4995 streamDesc.getVolumeIndex(device),
4996 output,
4997 device,
4998 delayMs);
4999 }
5000 }
5001}
5002
Eric Laurente0720872014-03-11 09:30:41 -07005003void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07005004 bool starting, bool stateChange)
Eric Laurente552edb2014-03-10 17:42:56 -07005005{
5006 // if the stream pertains to sonification strategy and we are in call we must
5007 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
5008 // in the device used for phone strategy and play the tone if the selected device does not
5009 // interfere with the device used for phone strategy
5010 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
5011 // many times as there are active tracks on the output
Eric Laurent3b73df72014-03-11 09:06:29 -07005012 const routing_strategy stream_strategy = getStrategy(stream);
Eric Laurente552edb2014-03-10 17:42:56 -07005013 if ((stream_strategy == STRATEGY_SONIFICATION) ||
5014 ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
Eric Laurent1f2f2232014-06-02 12:01:23 -07005015 sp<AudioOutputDescriptor> outputDesc = mOutputs.valueFor(mPrimaryOutput);
Eric Laurente552edb2014-03-10 17:42:56 -07005016 ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
5017 stream, starting, outputDesc->mDevice, stateChange);
5018 if (outputDesc->mRefCount[stream]) {
5019 int muteCount = 1;
5020 if (stateChange) {
5021 muteCount = outputDesc->mRefCount[stream];
5022 }
Eric Laurent3b73df72014-03-11 09:06:29 -07005023 if (audio_is_low_visibility(stream)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005024 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
5025 for (int i = 0; i < muteCount; i++) {
5026 setStreamMute(stream, starting, mPrimaryOutput);
5027 }
5028 } else {
5029 ALOGV("handleIncallSonification() high visibility");
5030 if (outputDesc->device() &
5031 getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
5032 ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
5033 for (int i = 0; i < muteCount; i++) {
5034 setStreamMute(stream, starting, mPrimaryOutput);
5035 }
5036 }
5037 if (starting) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005038 mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
5039 AUDIO_STREAM_VOICE_CALL);
Eric Laurente552edb2014-03-10 17:42:56 -07005040 } else {
5041 mpClientInterface->stopTone();
5042 }
5043 }
5044 }
5045 }
5046}
5047
Eric Laurente0720872014-03-11 09:30:41 -07005048bool AudioPolicyManager::isInCall()
Eric Laurente552edb2014-03-10 17:42:56 -07005049{
5050 return isStateInCall(mPhoneState);
5051}
5052
Eric Laurente0720872014-03-11 09:30:41 -07005053bool AudioPolicyManager::isStateInCall(int state) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005054 return ((state == AUDIO_MODE_IN_CALL) ||
5055 (state == AUDIO_MODE_IN_COMMUNICATION));
Eric Laurente552edb2014-03-10 17:42:56 -07005056}
5057
Eric Laurente0720872014-03-11 09:30:41 -07005058uint32_t AudioPolicyManager::getMaxEffectsCpuLoad()
Eric Laurente552edb2014-03-10 17:42:56 -07005059{
5060 return MAX_EFFECTS_CPU_LOAD;
5061}
5062
Eric Laurente0720872014-03-11 09:30:41 -07005063uint32_t AudioPolicyManager::getMaxEffectsMemory()
Eric Laurente552edb2014-03-10 17:42:56 -07005064{
5065 return MAX_EFFECTS_MEMORY;
5066}
5067
Eric Laurent6a94d692014-05-20 11:18:06 -07005068
Eric Laurente552edb2014-03-10 17:42:56 -07005069// --- AudioOutputDescriptor class implementation
5070
Eric Laurente0720872014-03-11 09:30:41 -07005071AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
Eric Laurent1c333e22014-05-20 10:48:17 -07005072 const sp<IOProfile>& profile)
Eric Laurent1f2f2232014-06-02 12:01:23 -07005073 : mId(0), mIoHandle(0), mLatency(0),
Eric Laurent1c333e22014-05-20 10:48:17 -07005074 mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0),
Eric Laurente552edb2014-03-10 17:42:56 -07005075 mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
5076{
5077 // clear usage count for all stream types
Eric Laurent3b73df72014-03-11 09:06:29 -07005078 for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
Eric Laurente552edb2014-03-10 17:42:56 -07005079 mRefCount[i] = 0;
5080 mCurVolume[i] = -1.0;
5081 mMuteCount[i] = 0;
5082 mStopTime[i] = 0;
5083 }
5084 for (int i = 0; i < NUM_STRATEGIES; i++) {
5085 mStrategyMutedByDevice[i] = false;
5086 }
5087 if (profile != NULL) {
Eric Laurentd8622372014-07-27 13:47:31 -07005088 mFlags = profile->mFlags;
Eric Laurent1e693b52014-07-09 15:03:28 -07005089 mSamplingRate = profile->pickSamplingRate();
5090 mFormat = profile->pickFormat();
5091 mChannelMask = profile->pickChannelMask();
Eric Laurenta121f902014-06-03 13:32:54 -07005092 if (profile->mGains.size() > 0) {
5093 profile->mGains[0]->getDefaultConfig(&mGain);
5094 }
Eric Laurente552edb2014-03-10 17:42:56 -07005095 }
5096}
5097
Eric Laurente0720872014-03-11 09:30:41 -07005098audio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const
Eric Laurente552edb2014-03-10 17:42:56 -07005099{
5100 if (isDuplicated()) {
5101 return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
5102 } else {
5103 return mDevice;
5104 }
5105}
5106
Eric Laurente0720872014-03-11 09:30:41 -07005107uint32_t AudioPolicyManager::AudioOutputDescriptor::latency()
Eric Laurente552edb2014-03-10 17:42:56 -07005108{
5109 if (isDuplicated()) {
5110 return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
5111 } else {
5112 return mLatency;
5113 }
5114}
5115
Eric Laurente0720872014-03-11 09:30:41 -07005116bool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
Eric Laurent1f2f2232014-06-02 12:01:23 -07005117 const sp<AudioOutputDescriptor> outputDesc)
Eric Laurente552edb2014-03-10 17:42:56 -07005118{
5119 if (isDuplicated()) {
5120 return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
5121 } else if (outputDesc->isDuplicated()){
5122 return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
5123 } else {
5124 return (mProfile->mModule == outputDesc->mProfile->mModule);
5125 }
5126}
5127
Eric Laurente0720872014-03-11 09:30:41 -07005128void AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
Eric Laurent3b73df72014-03-11 09:06:29 -07005129 int delta)
Eric Laurente552edb2014-03-10 17:42:56 -07005130{
5131 // forward usage count change to attached outputs
5132 if (isDuplicated()) {
5133 mOutput1->changeRefCount(stream, delta);
5134 mOutput2->changeRefCount(stream, delta);
5135 }
5136 if ((delta + (int)mRefCount[stream]) < 0) {
Eric Laurent3b73df72014-03-11 09:06:29 -07005137 ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
5138 delta, stream, mRefCount[stream]);
Eric Laurente552edb2014-03-10 17:42:56 -07005139 mRefCount[stream] = 0;
5140 return;
5141 }
5142 mRefCount[stream] += delta;
5143 ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
5144}
5145
Eric Laurente0720872014-03-11 09:30:41 -07005146audio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices()
Eric Laurente552edb2014-03-10 17:42:56 -07005147{
5148 if (isDuplicated()) {
5149 return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
5150 } else {
Eric Laurent3a4311c2014-03-17 12:00:47 -07005151 return mProfile->mSupportedDevices.types() ;
Eric Laurente552edb2014-03-10 17:42:56 -07005152 }
5153}
5154
Eric Laurente0720872014-03-11 09:30:41 -07005155bool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const
Eric Laurente552edb2014-03-10 17:42:56 -07005156{
5157 return isStrategyActive(NUM_STRATEGIES, inPastMs);
5158}
5159
Eric Laurente0720872014-03-11 09:30:41 -07005160bool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy,
Eric Laurente552edb2014-03-10 17:42:56 -07005161 uint32_t inPastMs,
5162 nsecs_t sysTime) const
5163{
5164 if ((sysTime == 0) && (inPastMs != 0)) {
5165 sysTime = systemTime();
5166 }
Eric Laurent3b73df72014-03-11 09:06:29 -07005167 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
5168 if (((getStrategy((audio_stream_type_t)i) == strategy) ||
Eric Laurente552edb2014-03-10 17:42:56 -07005169 (NUM_STRATEGIES == strategy)) &&
Eric Laurent3b73df72014-03-11 09:06:29 -07005170 isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
Eric Laurente552edb2014-03-10 17:42:56 -07005171 return true;
5172 }
5173 }
5174 return false;
5175}
5176
Eric Laurente0720872014-03-11 09:30:41 -07005177bool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
Eric Laurente552edb2014-03-10 17:42:56 -07005178 uint32_t inPastMs,
5179 nsecs_t sysTime) const
5180{
5181 if (mRefCount[stream] != 0) {
5182 return true;
5183 }
5184 if (inPastMs == 0) {
5185 return false;
5186 }
5187 if (sysTime == 0) {
5188 sysTime = systemTime();
5189 }
5190 if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
5191 return true;
5192 }
5193 return false;
5194}
5195
Eric Laurent1c333e22014-05-20 10:48:17 -07005196void AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig(
Eric Laurent6a94d692014-05-20 11:18:06 -07005197 struct audio_port_config *dstConfig,
5198 const struct audio_port_config *srcConfig) const
Eric Laurent1c333e22014-05-20 10:48:17 -07005199{
Eric Laurent84c70242014-06-23 08:46:27 -07005200 ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
5201
Eric Laurent1f2f2232014-06-02 12:01:23 -07005202 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
5203 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
5204 if (srcConfig != NULL) {
Eric Laurent84c70242014-06-23 08:46:27 -07005205 dstConfig->config_mask |= srcConfig->config_mask;
Eric Laurent1f2f2232014-06-02 12:01:23 -07005206 }
5207 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
5208
Eric Laurent6a94d692014-05-20 11:18:06 -07005209 dstConfig->id = mId;
5210 dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
5211 dstConfig->type = AUDIO_PORT_TYPE_MIX;
Eric Laurent6a94d692014-05-20 11:18:06 -07005212 dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
5213 dstConfig->ext.mix.handle = mIoHandle;
5214 dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
Eric Laurent1c333e22014-05-20 10:48:17 -07005215}
5216
5217void AudioPolicyManager::AudioOutputDescriptor::toAudioPort(
5218 struct audio_port *port) const
5219{
Eric Laurent84c70242014-06-23 08:46:27 -07005220 ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
Eric Laurent1c333e22014-05-20 10:48:17 -07005221 mProfile->toAudioPort(port);
5222 port->id = mId;
Eric Laurent6a94d692014-05-20 11:18:06 -07005223 toAudioPortConfig(&port->active_config);
5224 port->ext.mix.hw_module = mProfile->mModule->mHandle;
Eric Laurent1c333e22014-05-20 10:48:17 -07005225 port->ext.mix.handle = mIoHandle;
5226 port->ext.mix.latency_class =
5227 mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
5228}
Eric Laurente552edb2014-03-10 17:42:56 -07005229
Eric Laurente0720872014-03-11 09:30:41 -07005230status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07005231{
5232 const size_t SIZE = 256;
5233 char buffer[SIZE];
5234 String8 result;
5235
Eric Laurent4d416952014-08-10 14:07:09 -07005236 snprintf(buffer, SIZE, " ID: %d\n", mId);
5237 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07005238 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
5239 result.append(buffer);
5240 snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
5241 result.append(buffer);
5242 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
5243 result.append(buffer);
5244 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
5245 result.append(buffer);
5246 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
5247 result.append(buffer);
5248 snprintf(buffer, SIZE, " Devices %08x\n", device());
5249 result.append(buffer);
5250 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
5251 result.append(buffer);
Eric Laurent3b73df72014-03-11 09:06:29 -07005252 for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
5253 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n",
5254 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
Eric Laurente552edb2014-03-10 17:42:56 -07005255 result.append(buffer);
5256 }
5257 write(fd, result.string(), result.size());
5258
5259 return NO_ERROR;
5260}
5261
5262// --- AudioInputDescriptor class implementation
5263
Eric Laurent1c333e22014-05-20 10:48:17 -07005264AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
Eric Laurent1f2f2232014-06-02 12:01:23 -07005265 : mId(0), mIoHandle(0),
Eric Laurent1c333e22014-05-20 10:48:17 -07005266 mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0),
Eric Laurentdf3dc7e2014-07-27 18:39:40 -07005267 mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile), mIsSoundTrigger(false)
Eric Laurente552edb2014-03-10 17:42:56 -07005268{
Eric Laurent3a4311c2014-03-17 12:00:47 -07005269 if (profile != NULL) {
Eric Laurent1e693b52014-07-09 15:03:28 -07005270 mSamplingRate = profile->pickSamplingRate();
5271 mFormat = profile->pickFormat();
5272 mChannelMask = profile->pickChannelMask();
Eric Laurenta121f902014-06-03 13:32:54 -07005273 if (profile->mGains.size() > 0) {
5274 profile->mGains[0]->getDefaultConfig(&mGain);
5275 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07005276 }
Eric Laurente552edb2014-03-10 17:42:56 -07005277}
5278
Eric Laurent1c333e22014-05-20 10:48:17 -07005279void AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig(
Eric Laurent6a94d692014-05-20 11:18:06 -07005280 struct audio_port_config *dstConfig,
5281 const struct audio_port_config *srcConfig) const
Eric Laurent1c333e22014-05-20 10:48:17 -07005282{
Eric Laurent84c70242014-06-23 08:46:27 -07005283 ALOG_ASSERT(mProfile != 0,
5284 "toAudioPortConfig() called on input with null profile %d", mIoHandle);
Eric Laurent1f2f2232014-06-02 12:01:23 -07005285 dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
5286 AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
5287 if (srcConfig != NULL) {
Eric Laurent84c70242014-06-23 08:46:27 -07005288 dstConfig->config_mask |= srcConfig->config_mask;
Eric Laurent1f2f2232014-06-02 12:01:23 -07005289 }
5290
5291 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
5292
Eric Laurent6a94d692014-05-20 11:18:06 -07005293 dstConfig->id = mId;
5294 dstConfig->role = AUDIO_PORT_ROLE_SINK;
5295 dstConfig->type = AUDIO_PORT_TYPE_MIX;
Eric Laurent62aaabb2014-06-02 10:40:54 -07005296 dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
5297 dstConfig->ext.mix.handle = mIoHandle;
5298 dstConfig->ext.mix.usecase.source = mInputSource;
Eric Laurent1c333e22014-05-20 10:48:17 -07005299}
5300
5301void AudioPolicyManager::AudioInputDescriptor::toAudioPort(
5302 struct audio_port *port) const
5303{
Eric Laurent84c70242014-06-23 08:46:27 -07005304 ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
5305
Eric Laurent1c333e22014-05-20 10:48:17 -07005306 mProfile->toAudioPort(port);
5307 port->id = mId;
Eric Laurent6a94d692014-05-20 11:18:06 -07005308 toAudioPortConfig(&port->active_config);
5309 port->ext.mix.hw_module = mProfile->mModule->mHandle;
Eric Laurent1c333e22014-05-20 10:48:17 -07005310 port->ext.mix.handle = mIoHandle;
5311 port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
5312}
5313
Eric Laurente0720872014-03-11 09:30:41 -07005314status_t AudioPolicyManager::AudioInputDescriptor::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07005315{
5316 const size_t SIZE = 256;
5317 char buffer[SIZE];
5318 String8 result;
5319
Eric Laurent4d416952014-08-10 14:07:09 -07005320 snprintf(buffer, SIZE, " ID: %d\n", mId);
5321 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07005322 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
5323 result.append(buffer);
5324 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
5325 result.append(buffer);
5326 snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
5327 result.append(buffer);
5328 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
5329 result.append(buffer);
5330 snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
5331 result.append(buffer);
Glenn Kasten6a8ab052014-07-24 14:08:35 -07005332 snprintf(buffer, SIZE, " Open Ref Count %d\n", mOpenRefCount);
5333 result.append(buffer);
5334
Eric Laurente552edb2014-03-10 17:42:56 -07005335 write(fd, result.string(), result.size());
5336
5337 return NO_ERROR;
5338}
5339
5340// --- StreamDescriptor class implementation
5341
Eric Laurente0720872014-03-11 09:30:41 -07005342AudioPolicyManager::StreamDescriptor::StreamDescriptor()
Eric Laurente552edb2014-03-10 17:42:56 -07005343 : mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
5344{
5345 mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
5346}
5347
Eric Laurente0720872014-03-11 09:30:41 -07005348int AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device)
Eric Laurente552edb2014-03-10 17:42:56 -07005349{
Eric Laurente0720872014-03-11 09:30:41 -07005350 device = AudioPolicyManager::getDeviceForVolume(device);
Eric Laurente552edb2014-03-10 17:42:56 -07005351 // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
5352 if (mIndexCur.indexOfKey(device) < 0) {
5353 device = AUDIO_DEVICE_OUT_DEFAULT;
5354 }
5355 return mIndexCur.valueFor(device);
5356}
5357
Eric Laurente0720872014-03-11 09:30:41 -07005358void AudioPolicyManager::StreamDescriptor::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07005359{
5360 const size_t SIZE = 256;
5361 char buffer[SIZE];
5362 String8 result;
5363
5364 snprintf(buffer, SIZE, "%s %02d %02d ",
5365 mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
5366 result.append(buffer);
5367 for (size_t i = 0; i < mIndexCur.size(); i++) {
5368 snprintf(buffer, SIZE, "%04x : %02d, ",
5369 mIndexCur.keyAt(i),
5370 mIndexCur.valueAt(i));
5371 result.append(buffer);
5372 }
5373 result.append("\n");
5374
5375 write(fd, result.string(), result.size());
5376}
5377
5378// --- EffectDescriptor class implementation
5379
Eric Laurente0720872014-03-11 09:30:41 -07005380status_t AudioPolicyManager::EffectDescriptor::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07005381{
5382 const size_t SIZE = 256;
5383 char buffer[SIZE];
5384 String8 result;
5385
5386 snprintf(buffer, SIZE, " I/O: %d\n", mIo);
5387 result.append(buffer);
5388 snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
5389 result.append(buffer);
5390 snprintf(buffer, SIZE, " Session: %d\n", mSession);
5391 result.append(buffer);
5392 snprintf(buffer, SIZE, " Name: %s\n", mDesc.name);
5393 result.append(buffer);
5394 snprintf(buffer, SIZE, " %s\n", mEnabled ? "Enabled" : "Disabled");
5395 result.append(buffer);
5396 write(fd, result.string(), result.size());
5397
5398 return NO_ERROR;
5399}
5400
Eric Laurent1c333e22014-05-20 10:48:17 -07005401// --- HwModule class implementation
Eric Laurente552edb2014-03-10 17:42:56 -07005402
Eric Laurente0720872014-03-11 09:30:41 -07005403AudioPolicyManager::HwModule::HwModule(const char *name)
Eric Laurenteb108a42014-06-06 14:56:52 -07005404 : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)),
5405 mHalVersion(AUDIO_DEVICE_API_VERSION_MIN), mHandle(0)
Eric Laurente552edb2014-03-10 17:42:56 -07005406{
5407}
5408
Eric Laurente0720872014-03-11 09:30:41 -07005409AudioPolicyManager::HwModule::~HwModule()
Eric Laurente552edb2014-03-10 17:42:56 -07005410{
5411 for (size_t i = 0; i < mOutputProfiles.size(); i++) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07005412 mOutputProfiles[i]->mSupportedDevices.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07005413 }
5414 for (size_t i = 0; i < mInputProfiles.size(); i++) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07005415 mInputProfiles[i]->mSupportedDevices.clear();
Eric Laurente552edb2014-03-10 17:42:56 -07005416 }
5417 free((void *)mName);
5418}
5419
Eric Laurent1afeecb2014-05-14 08:52:28 -07005420status_t AudioPolicyManager::HwModule::loadInput(cnode *root)
5421{
5422 cnode *node = root->first_child;
5423
5424 sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
5425
5426 while (node) {
5427 if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
5428 profile->loadSamplingRates((char *)node->value);
5429 } else if (strcmp(node->name, FORMATS_TAG) == 0) {
5430 profile->loadFormats((char *)node->value);
5431 } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
5432 profile->loadInChannels((char *)node->value);
5433 } else if (strcmp(node->name, DEVICES_TAG) == 0) {
5434 profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
5435 mDeclaredDevices);
5436 } else if (strcmp(node->name, GAINS_TAG) == 0) {
5437 profile->loadGains(node);
5438 }
5439 node = node->next;
5440 }
5441 ALOGW_IF(profile->mSupportedDevices.isEmpty(),
5442 "loadInput() invalid supported devices");
5443 ALOGW_IF(profile->mChannelMasks.size() == 0,
5444 "loadInput() invalid supported channel masks");
5445 ALOGW_IF(profile->mSamplingRates.size() == 0,
5446 "loadInput() invalid supported sampling rates");
5447 ALOGW_IF(profile->mFormats.size() == 0,
5448 "loadInput() invalid supported formats");
5449 if (!profile->mSupportedDevices.isEmpty() &&
5450 (profile->mChannelMasks.size() != 0) &&
5451 (profile->mSamplingRates.size() != 0) &&
5452 (profile->mFormats.size() != 0)) {
5453
5454 ALOGV("loadInput() adding input Supported Devices %04x",
5455 profile->mSupportedDevices.types());
5456
5457 mInputProfiles.add(profile);
5458 return NO_ERROR;
5459 } else {
5460 return BAD_VALUE;
5461 }
5462}
5463
5464status_t AudioPolicyManager::HwModule::loadOutput(cnode *root)
5465{
5466 cnode *node = root->first_child;
5467
5468 sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
5469
5470 while (node) {
5471 if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
5472 profile->loadSamplingRates((char *)node->value);
5473 } else if (strcmp(node->name, FORMATS_TAG) == 0) {
5474 profile->loadFormats((char *)node->value);
5475 } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
5476 profile->loadOutChannels((char *)node->value);
5477 } else if (strcmp(node->name, DEVICES_TAG) == 0) {
5478 profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
5479 mDeclaredDevices);
5480 } else if (strcmp(node->name, FLAGS_TAG) == 0) {
5481 profile->mFlags = parseFlagNames((char *)node->value);
5482 } else if (strcmp(node->name, GAINS_TAG) == 0) {
5483 profile->loadGains(node);
5484 }
5485 node = node->next;
5486 }
5487 ALOGW_IF(profile->mSupportedDevices.isEmpty(),
5488 "loadOutput() invalid supported devices");
5489 ALOGW_IF(profile->mChannelMasks.size() == 0,
5490 "loadOutput() invalid supported channel masks");
5491 ALOGW_IF(profile->mSamplingRates.size() == 0,
5492 "loadOutput() invalid supported sampling rates");
5493 ALOGW_IF(profile->mFormats.size() == 0,
5494 "loadOutput() invalid supported formats");
5495 if (!profile->mSupportedDevices.isEmpty() &&
5496 (profile->mChannelMasks.size() != 0) &&
5497 (profile->mSamplingRates.size() != 0) &&
5498 (profile->mFormats.size() != 0)) {
5499
5500 ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
5501 profile->mSupportedDevices.types(), profile->mFlags);
5502
5503 mOutputProfiles.add(profile);
5504 return NO_ERROR;
5505 } else {
5506 return BAD_VALUE;
5507 }
5508}
5509
5510status_t AudioPolicyManager::HwModule::loadDevice(cnode *root)
5511{
5512 cnode *node = root->first_child;
5513
5514 audio_devices_t type = AUDIO_DEVICE_NONE;
5515 while (node) {
5516 if (strcmp(node->name, DEVICE_TYPE) == 0) {
5517 type = parseDeviceNames((char *)node->value);
5518 break;
5519 }
5520 node = node->next;
5521 }
5522 if (type == AUDIO_DEVICE_NONE ||
5523 (!audio_is_input_device(type) && !audio_is_output_device(type))) {
5524 ALOGW("loadDevice() bad type %08x", type);
5525 return BAD_VALUE;
5526 }
5527 sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
5528 deviceDesc->mModule = this;
5529
5530 node = root->first_child;
5531 while (node) {
5532 if (strcmp(node->name, DEVICE_ADDRESS) == 0) {
5533 deviceDesc->mAddress = String8((char *)node->value);
5534 } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
5535 if (audio_is_input_device(type)) {
5536 deviceDesc->loadInChannels((char *)node->value);
5537 } else {
5538 deviceDesc->loadOutChannels((char *)node->value);
5539 }
5540 } else if (strcmp(node->name, GAINS_TAG) == 0) {
5541 deviceDesc->loadGains(node);
5542 }
5543 node = node->next;
5544 }
5545
5546 ALOGV("loadDevice() adding device name %s type %08x address %s",
5547 deviceDesc->mName.string(), type, deviceDesc->mAddress.string());
5548
5549 mDeclaredDevices.add(deviceDesc);
5550
5551 return NO_ERROR;
5552}
5553
Eric Laurente0720872014-03-11 09:30:41 -07005554void AudioPolicyManager::HwModule::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07005555{
5556 const size_t SIZE = 256;
5557 char buffer[SIZE];
5558 String8 result;
5559
5560 snprintf(buffer, SIZE, " - name: %s\n", mName);
5561 result.append(buffer);
5562 snprintf(buffer, SIZE, " - handle: %d\n", mHandle);
5563 result.append(buffer);
Eric Laurenteb108a42014-06-06 14:56:52 -07005564 snprintf(buffer, SIZE, " - version: %u.%u\n", mHalVersion >> 8, mHalVersion & 0xFF);
5565 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07005566 write(fd, result.string(), result.size());
5567 if (mOutputProfiles.size()) {
5568 write(fd, " - outputs:\n", strlen(" - outputs:\n"));
5569 for (size_t i = 0; i < mOutputProfiles.size(); i++) {
Eric Laurentd4692962014-05-05 18:13:44 -07005570 snprintf(buffer, SIZE, " output %zu:\n", i);
Eric Laurente552edb2014-03-10 17:42:56 -07005571 write(fd, buffer, strlen(buffer));
5572 mOutputProfiles[i]->dump(fd);
5573 }
5574 }
5575 if (mInputProfiles.size()) {
5576 write(fd, " - inputs:\n", strlen(" - inputs:\n"));
5577 for (size_t i = 0; i < mInputProfiles.size(); i++) {
Eric Laurentd4692962014-05-05 18:13:44 -07005578 snprintf(buffer, SIZE, " input %zu:\n", i);
Eric Laurente552edb2014-03-10 17:42:56 -07005579 write(fd, buffer, strlen(buffer));
5580 mInputProfiles[i]->dump(fd);
5581 }
5582 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07005583 if (mDeclaredDevices.size()) {
5584 write(fd, " - devices:\n", strlen(" - devices:\n"));
5585 for (size_t i = 0; i < mDeclaredDevices.size(); i++) {
5586 mDeclaredDevices[i]->dump(fd, 4, i);
5587 }
5588 }
Eric Laurente552edb2014-03-10 17:42:56 -07005589}
5590
Eric Laurent1c333e22014-05-20 10:48:17 -07005591// --- AudioPort class implementation
5592
Eric Laurenta121f902014-06-03 13:32:54 -07005593
5594AudioPolicyManager::AudioPort::AudioPort(const String8& name, audio_port_type_t type,
5595 audio_port_role_t role, const sp<HwModule>& module) :
Eric Laurent1e693b52014-07-09 15:03:28 -07005596 mName(name), mType(type), mRole(role), mModule(module), mFlags((audio_output_flags_t)0)
Eric Laurenta121f902014-06-03 13:32:54 -07005597{
5598 mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) ||
5599 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK));
5600}
5601
Eric Laurent1c333e22014-05-20 10:48:17 -07005602void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const
5603{
5604 port->role = mRole;
5605 port->type = mType;
5606 unsigned int i;
5607 for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07005608 if (mSamplingRates[i] != 0) {
5609 port->sample_rates[i] = mSamplingRates[i];
5610 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005611 }
5612 port->num_sample_rates = i;
5613 for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07005614 if (mChannelMasks[i] != 0) {
5615 port->channel_masks[i] = mChannelMasks[i];
5616 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005617 }
5618 port->num_channel_masks = i;
5619 for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) {
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07005620 if (mFormats[i] != 0) {
5621 port->formats[i] = mFormats[i];
5622 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005623 }
5624 port->num_formats = i;
Eric Laurente1715a42014-05-20 11:30:42 -07005625
Mark Salyzynbeb9e302014-06-18 16:33:15 -07005626 ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
Eric Laurente1715a42014-05-20 11:30:42 -07005627
5628 for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
5629 port->gains[i] = mGains[i]->mGain;
5630 }
5631 port->num_gains = i;
Eric Laurent1c333e22014-05-20 10:48:17 -07005632}
5633
Jean-Michel Trivif17026d2014-08-10 14:30:48 -07005634void AudioPolicyManager::AudioPort::importAudioPort(const sp<AudioPort> port) {
5635 for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) {
5636 const uint32_t rate = port->mSamplingRates.itemAt(k);
5637 if (rate != 0) { // skip "dynamic" rates
5638 bool hasRate = false;
5639 for (size_t l = 0 ; l < mSamplingRates.size() ; l++) {
5640 if (rate == mSamplingRates.itemAt(l)) {
5641 hasRate = true;
5642 break;
5643 }
5644 }
5645 if (!hasRate) { // never import a sampling rate twice
5646 mSamplingRates.add(rate);
5647 }
5648 }
5649 }
5650 for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) {
5651 const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k);
5652 if (mask != 0) { // skip "dynamic" masks
5653 bool hasMask = false;
5654 for (size_t l = 0 ; l < mChannelMasks.size() ; l++) {
5655 if (mask == mChannelMasks.itemAt(l)) {
5656 hasMask = true;
5657 break;
5658 }
5659 }
5660 if (!hasMask) { // never import a channel mask twice
5661 mChannelMasks.add(mask);
5662 }
5663 }
5664 }
5665 for (size_t k = 0 ; k < port->mFormats.size() ; k++) {
5666 const audio_format_t format = port->mFormats.itemAt(k);
5667 if (format != 0) { // skip "dynamic" formats
5668 bool hasFormat = false;
5669 for (size_t l = 0 ; l < mFormats.size() ; l++) {
5670 if (format == mFormats.itemAt(l)) {
5671 hasFormat = true;
5672 break;
5673 }
5674 }
5675 if (!hasFormat) { // never import a channel mask twice
5676 mFormats.add(format);
5677 }
5678 }
5679 }
5680}
5681
5682void AudioPolicyManager::AudioPort::clearCapabilities() {
5683 mChannelMasks.clear();
5684 mFormats.clear();
5685 mSamplingRates.clear();
5686}
Eric Laurent1c333e22014-05-20 10:48:17 -07005687
5688void AudioPolicyManager::AudioPort::loadSamplingRates(char *name)
5689{
5690 char *str = strtok(name, "|");
5691
5692 // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
5693 // rates should be read from the output stream after it is opened for the first time
5694 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
5695 mSamplingRates.add(0);
5696 return;
5697 }
5698
5699 while (str != NULL) {
5700 uint32_t rate = atoi(str);
5701 if (rate != 0) {
5702 ALOGV("loadSamplingRates() adding rate %d", rate);
5703 mSamplingRates.add(rate);
5704 }
5705 str = strtok(NULL, "|");
5706 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005707}
5708
5709void AudioPolicyManager::AudioPort::loadFormats(char *name)
5710{
5711 char *str = strtok(name, "|");
5712
5713 // by convention, "0' in the first entry in mFormats indicates the supported formats
5714 // should be read from the output stream after it is opened for the first time
5715 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
5716 mFormats.add(AUDIO_FORMAT_DEFAULT);
5717 return;
5718 }
5719
5720 while (str != NULL) {
5721 audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable,
5722 ARRAY_SIZE(sFormatNameToEnumTable),
5723 str);
5724 if (format != AUDIO_FORMAT_DEFAULT) {
5725 mFormats.add(format);
5726 }
5727 str = strtok(NULL, "|");
5728 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005729}
5730
5731void AudioPolicyManager::AudioPort::loadInChannels(char *name)
5732{
5733 const char *str = strtok(name, "|");
5734
5735 ALOGV("loadInChannels() %s", name);
5736
5737 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
5738 mChannelMasks.add(0);
5739 return;
5740 }
5741
5742 while (str != NULL) {
5743 audio_channel_mask_t channelMask =
5744 (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
5745 ARRAY_SIZE(sInChannelsNameToEnumTable),
5746 str);
5747 if (channelMask != 0) {
5748 ALOGV("loadInChannels() adding channelMask %04x", channelMask);
5749 mChannelMasks.add(channelMask);
5750 }
5751 str = strtok(NULL, "|");
5752 }
Eric Laurent1c333e22014-05-20 10:48:17 -07005753}
5754
5755void AudioPolicyManager::AudioPort::loadOutChannels(char *name)
5756{
5757 const char *str = strtok(name, "|");
5758
5759 ALOGV("loadOutChannels() %s", name);
5760
5761 // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
5762 // masks should be read from the output stream after it is opened for the first time
5763 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
5764 mChannelMasks.add(0);
5765 return;
5766 }
5767
5768 while (str != NULL) {
5769 audio_channel_mask_t channelMask =
5770 (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
5771 ARRAY_SIZE(sOutChannelsNameToEnumTable),
5772 str);
5773 if (channelMask != 0) {
5774 mChannelMasks.add(channelMask);
5775 }
5776 str = strtok(NULL, "|");
5777 }
5778 return;
5779}
5780
Eric Laurent1afeecb2014-05-14 08:52:28 -07005781audio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name)
5782{
5783 const char *str = strtok(name, "|");
5784
5785 ALOGV("loadGainMode() %s", name);
5786 audio_gain_mode_t mode = 0;
5787 while (str != NULL) {
5788 mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable,
5789 ARRAY_SIZE(sGainModeNameToEnumTable),
5790 str);
5791 str = strtok(NULL, "|");
5792 }
5793 return mode;
5794}
5795
Eric Laurenta121f902014-06-03 13:32:54 -07005796void AudioPolicyManager::AudioPort::loadGain(cnode *root, int index)
Eric Laurent1afeecb2014-05-14 08:52:28 -07005797{
5798 cnode *node = root->first_child;
5799
Eric Laurenta121f902014-06-03 13:32:54 -07005800 sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask);
Eric Laurent1afeecb2014-05-14 08:52:28 -07005801
5802 while (node) {
5803 if (strcmp(node->name, GAIN_MODE) == 0) {
5804 gain->mGain.mode = loadGainMode((char *)node->value);
5805 } else if (strcmp(node->name, GAIN_CHANNELS) == 0) {
Eric Laurenta121f902014-06-03 13:32:54 -07005806 if (mUseInChannelMask) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07005807 gain->mGain.channel_mask =
5808 (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
5809 ARRAY_SIZE(sInChannelsNameToEnumTable),
5810 (char *)node->value);
5811 } else {
5812 gain->mGain.channel_mask =
5813 (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
5814 ARRAY_SIZE(sOutChannelsNameToEnumTable),
5815 (char *)node->value);
5816 }
5817 } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) {
5818 gain->mGain.min_value = atoi((char *)node->value);
5819 } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) {
5820 gain->mGain.max_value = atoi((char *)node->value);
5821 } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) {
5822 gain->mGain.default_value = atoi((char *)node->value);
5823 } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) {
5824 gain->mGain.step_value = atoi((char *)node->value);
5825 } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) {
5826 gain->mGain.min_ramp_ms = atoi((char *)node->value);
5827 } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) {
5828 gain->mGain.max_ramp_ms = atoi((char *)node->value);
5829 }
5830 node = node->next;
5831 }
5832
5833 ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d",
5834 gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value);
5835
5836 if (gain->mGain.mode == 0) {
5837 return;
5838 }
5839 mGains.add(gain);
5840}
5841
5842void AudioPolicyManager::AudioPort::loadGains(cnode *root)
5843{
5844 cnode *node = root->first_child;
Eric Laurenta121f902014-06-03 13:32:54 -07005845 int index = 0;
Eric Laurent1afeecb2014-05-14 08:52:28 -07005846 while (node) {
5847 ALOGV("loadGains() loading gain %s", node->name);
Eric Laurenta121f902014-06-03 13:32:54 -07005848 loadGain(node, index++);
Eric Laurent1afeecb2014-05-14 08:52:28 -07005849 node = node->next;
5850 }
5851}
5852
Glenn Kastencbd48022014-07-24 13:46:44 -07005853status_t AudioPolicyManager::AudioPort::checkExactSamplingRate(uint32_t samplingRate) const
Eric Laurenta121f902014-06-03 13:32:54 -07005854{
5855 for (size_t i = 0; i < mSamplingRates.size(); i ++) {
5856 if (mSamplingRates[i] == samplingRate) {
5857 return NO_ERROR;
5858 }
5859 }
5860 return BAD_VALUE;
5861}
5862
Glenn Kastencbd48022014-07-24 13:46:44 -07005863status_t AudioPolicyManager::AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate,
5864 uint32_t *updatedSamplingRate) const
Eric Laurenta121f902014-06-03 13:32:54 -07005865{
Glenn Kastencbd48022014-07-24 13:46:44 -07005866 // Search for the closest supported sampling rate that is above (preferred)
5867 // or below (acceptable) the desired sampling rate, within a permitted ratio.
5868 // The sampling rates do not need to be sorted in ascending order.
5869 ssize_t maxBelow = -1;
5870 ssize_t minAbove = -1;
5871 uint32_t candidate;
5872 for (size_t i = 0; i < mSamplingRates.size(); i++) {
5873 candidate = mSamplingRates[i];
5874 if (candidate == samplingRate) {
5875 if (updatedSamplingRate != NULL) {
5876 *updatedSamplingRate = candidate;
5877 }
5878 return NO_ERROR;
5879 }
5880 // candidate < desired
5881 if (candidate < samplingRate) {
5882 if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) {
5883 maxBelow = i;
5884 }
5885 // candidate > desired
5886 } else {
5887 if (minAbove < 0 || candidate < mSamplingRates[minAbove]) {
5888 minAbove = i;
5889 }
5890 }
5891 }
5892 // This uses hard-coded knowledge about AudioFlinger resampling ratios.
5893 // TODO Move these assumptions out.
5894 static const uint32_t kMaxDownSampleRatio = 6; // beyond this aliasing occurs
5895 static const uint32_t kMaxUpSampleRatio = 256; // beyond this sample rate inaccuracies occur
5896 // due to approximation by an int32_t of the
5897 // phase increments
5898 // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum.
5899 if (minAbove >= 0) {
5900 candidate = mSamplingRates[minAbove];
5901 if (candidate / kMaxDownSampleRatio <= samplingRate) {
5902 if (updatedSamplingRate != NULL) {
5903 *updatedSamplingRate = candidate;
5904 }
5905 return NO_ERROR;
5906 }
5907 }
5908 // But if we have to up-sample from a lower sampling rate, that's OK.
5909 if (maxBelow >= 0) {
5910 candidate = mSamplingRates[maxBelow];
5911 if (candidate * kMaxUpSampleRatio >= samplingRate) {
5912 if (updatedSamplingRate != NULL) {
5913 *updatedSamplingRate = candidate;
5914 }
5915 return NO_ERROR;
5916 }
5917 }
5918 // leave updatedSamplingRate unmodified
5919 return BAD_VALUE;
5920}
5921
5922status_t AudioPolicyManager::AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const
5923{
5924 for (size_t i = 0; i < mChannelMasks.size(); i++) {
Eric Laurenta121f902014-06-03 13:32:54 -07005925 if (mChannelMasks[i] == channelMask) {
5926 return NO_ERROR;
5927 }
5928 }
5929 return BAD_VALUE;
5930}
5931
Glenn Kastencbd48022014-07-24 13:46:44 -07005932status_t AudioPolicyManager::AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask)
5933 const
5934{
5935 const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
5936 for (size_t i = 0; i < mChannelMasks.size(); i ++) {
5937 // FIXME Does not handle multi-channel automatic conversions yet
5938 audio_channel_mask_t supported = mChannelMasks[i];
5939 if (supported == channelMask) {
5940 return NO_ERROR;
5941 }
5942 if (isRecordThread) {
5943 // This uses hard-coded knowledge that AudioFlinger can silently down-mix and up-mix.
5944 // FIXME Abstract this out to a table.
5945 if (((supported == AUDIO_CHANNEL_IN_FRONT_BACK || supported == AUDIO_CHANNEL_IN_STEREO)
5946 && channelMask == AUDIO_CHANNEL_IN_MONO) ||
5947 (supported == AUDIO_CHANNEL_IN_MONO && (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK
5948 || channelMask == AUDIO_CHANNEL_IN_STEREO))) {
5949 return NO_ERROR;
5950 }
5951 }
5952 }
5953 return BAD_VALUE;
5954}
5955
Eric Laurenta121f902014-06-03 13:32:54 -07005956status_t AudioPolicyManager::AudioPort::checkFormat(audio_format_t format) const
5957{
5958 for (size_t i = 0; i < mFormats.size(); i ++) {
5959 if (mFormats[i] == format) {
5960 return NO_ERROR;
5961 }
5962 }
5963 return BAD_VALUE;
5964}
5965
Eric Laurent1e693b52014-07-09 15:03:28 -07005966
5967uint32_t AudioPolicyManager::AudioPort::pickSamplingRate() const
5968{
5969 // special case for uninitialized dynamic profile
5970 if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) {
5971 return 0;
5972 }
5973
5974 uint32_t samplingRate = 0;
5975 uint32_t maxRate = MAX_MIXER_SAMPLING_RATE;
5976
5977 // For mixed output and inputs, use max mixer sampling rates. Do not
5978 // limit sampling rate otherwise
5979 if ((mType != AUDIO_PORT_TYPE_MIX) ||
5980 ((mRole == AUDIO_PORT_ROLE_SOURCE) &&
5981 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) {
5982 maxRate = UINT_MAX;
5983 }
5984 for (size_t i = 0; i < mSamplingRates.size(); i ++) {
5985 if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) {
5986 samplingRate = mSamplingRates[i];
5987 }
5988 }
5989 return samplingRate;
5990}
5991
5992audio_channel_mask_t AudioPolicyManager::AudioPort::pickChannelMask() const
5993{
5994 // special case for uninitialized dynamic profile
5995 if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) {
5996 return AUDIO_CHANNEL_NONE;
5997 }
5998
5999 audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE;
6000 uint32_t channelCount = 0;
6001 uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT;
6002
6003 // For mixed output and inputs, use max mixer channel count. Do not
6004 // limit channel count otherwise
6005 if ((mType != AUDIO_PORT_TYPE_MIX) ||
6006 ((mRole == AUDIO_PORT_ROLE_SOURCE) &&
6007 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)))) {
6008 maxCount = UINT_MAX;
6009 }
6010 for (size_t i = 0; i < mChannelMasks.size(); i ++) {
6011 uint32_t cnlCount;
6012 if (mUseInChannelMask) {
6013 cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]);
6014 } else {
6015 cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]);
6016 }
6017 if ((cnlCount > channelCount) && (cnlCount <= maxCount)) {
6018 channelMask = mChannelMasks[i];
6019 }
6020 }
6021 return channelMask;
6022}
6023
Andy Hung9a605382014-07-28 16:16:31 -07006024/* format in order of increasing preference */
Eric Laurent1e693b52014-07-09 15:03:28 -07006025const audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = {
6026 AUDIO_FORMAT_DEFAULT,
6027 AUDIO_FORMAT_PCM_16_BIT,
Eric Laurenta2049942014-07-21 17:49:25 -07006028 AUDIO_FORMAT_PCM_8_24_BIT,
Eric Laurent1e693b52014-07-09 15:03:28 -07006029 AUDIO_FORMAT_PCM_24_BIT_PACKED,
Eric Laurenta2049942014-07-21 17:49:25 -07006030 AUDIO_FORMAT_PCM_32_BIT,
Andy Hung9a605382014-07-28 16:16:31 -07006031 AUDIO_FORMAT_PCM_FLOAT,
Eric Laurent1e693b52014-07-09 15:03:28 -07006032};
6033
6034int AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1,
6035 audio_format_t format2)
6036{
6037 // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any
6038 // compressed format and better than any PCM format. This is by design of pickFormat()
6039 if (!audio_is_linear_pcm(format1)) {
6040 if (!audio_is_linear_pcm(format2)) {
6041 return 0;
6042 }
6043 return 1;
6044 }
6045 if (!audio_is_linear_pcm(format2)) {
6046 return -1;
6047 }
6048
6049 int index1 = -1, index2 = -1;
6050 for (size_t i = 0;
6051 (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1));
6052 i ++) {
6053 if (sPcmFormatCompareTable[i] == format1) {
6054 index1 = i;
6055 }
6056 if (sPcmFormatCompareTable[i] == format2) {
6057 index2 = i;
6058 }
6059 }
6060 // format1 not found => index1 < 0 => format2 > format1
6061 // format2 not found => index2 < 0 => format2 < format1
6062 return index1 - index2;
6063}
6064
6065audio_format_t AudioPolicyManager::AudioPort::pickFormat() const
6066{
6067 // special case for uninitialized dynamic profile
6068 if (mFormats.size() == 1 && mFormats[0] == 0) {
6069 return AUDIO_FORMAT_DEFAULT;
6070 }
6071
6072 audio_format_t format = AUDIO_FORMAT_DEFAULT;
Andy Hung9a605382014-07-28 16:16:31 -07006073 audio_format_t bestFormat =
6074 AudioPolicyManager::AudioPort::sPcmFormatCompareTable[
6075 ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1];
Eric Laurent1e693b52014-07-09 15:03:28 -07006076 // For mixed output and inputs, use best mixer output format. Do not
6077 // limit format otherwise
6078 if ((mType != AUDIO_PORT_TYPE_MIX) ||
6079 ((mRole == AUDIO_PORT_ROLE_SOURCE) &&
Eric Laurentd8622372014-07-27 13:47:31 -07006080 (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) {
Eric Laurent1e693b52014-07-09 15:03:28 -07006081 bestFormat = AUDIO_FORMAT_INVALID;
6082 }
6083
6084 for (size_t i = 0; i < mFormats.size(); i ++) {
6085 if ((compareFormats(mFormats[i], format) > 0) &&
6086 (compareFormats(mFormats[i], bestFormat) <= 0)) {
6087 format = mFormats[i];
6088 }
6089 }
6090 return format;
6091}
6092
Eric Laurenta121f902014-06-03 13:32:54 -07006093status_t AudioPolicyManager::AudioPort::checkGain(const struct audio_gain_config *gainConfig,
6094 int index) const
6095{
6096 if (index < 0 || (size_t)index >= mGains.size()) {
6097 return BAD_VALUE;
6098 }
6099 return mGains[index]->checkConfig(gainConfig);
6100}
6101
Eric Laurent1afeecb2014-05-14 08:52:28 -07006102void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const
6103{
6104 const size_t SIZE = 256;
6105 char buffer[SIZE];
6106 String8 result;
6107
6108 if (mName.size() != 0) {
6109 snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
6110 result.append(buffer);
6111 }
6112
6113 if (mSamplingRates.size() != 0) {
6114 snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, "");
6115 result.append(buffer);
6116 for (size_t i = 0; i < mSamplingRates.size(); i++) {
Eric Laurent1e693b52014-07-09 15:03:28 -07006117 if (i == 0 && mSamplingRates[i] == 0) {
6118 snprintf(buffer, SIZE, "Dynamic");
6119 } else {
6120 snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
6121 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006122 result.append(buffer);
6123 result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
6124 }
6125 result.append("\n");
6126 }
6127
6128 if (mChannelMasks.size() != 0) {
6129 snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, "");
6130 result.append(buffer);
6131 for (size_t i = 0; i < mChannelMasks.size(); i++) {
Eric Laurent1e693b52014-07-09 15:03:28 -07006132 ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]);
6133
6134 if (i == 0 && mChannelMasks[i] == 0) {
6135 snprintf(buffer, SIZE, "Dynamic");
6136 } else {
6137 snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
6138 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006139 result.append(buffer);
6140 result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
6141 }
6142 result.append("\n");
6143 }
6144
6145 if (mFormats.size() != 0) {
6146 snprintf(buffer, SIZE, "%*s- formats: ", spaces, "");
6147 result.append(buffer);
6148 for (size_t i = 0; i < mFormats.size(); i++) {
Eric Laurent1e693b52014-07-09 15:03:28 -07006149 const char *formatStr = enumToString(sFormatNameToEnumTable,
6150 ARRAY_SIZE(sFormatNameToEnumTable),
6151 mFormats[i]);
6152 if (i == 0 && strcmp(formatStr, "") == 0) {
6153 snprintf(buffer, SIZE, "Dynamic");
6154 } else {
Eric Laurentcf2c0212014-07-25 16:20:43 -07006155 snprintf(buffer, SIZE, "%s", formatStr);
Eric Laurent1e693b52014-07-09 15:03:28 -07006156 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006157 result.append(buffer);
6158 result.append(i == (mFormats.size() - 1) ? "" : ", ");
6159 }
6160 result.append("\n");
6161 }
6162 write(fd, result.string(), result.size());
6163 if (mGains.size() != 0) {
6164 snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
6165 write(fd, buffer, strlen(buffer) + 1);
6166 result.append(buffer);
6167 for (size_t i = 0; i < mGains.size(); i++) {
6168 mGains[i]->dump(fd, spaces + 2, i);
6169 }
6170 }
6171}
6172
6173// --- AudioGain class implementation
6174
Eric Laurenta121f902014-06-03 13:32:54 -07006175AudioPolicyManager::AudioGain::AudioGain(int index, bool useInChannelMask)
Eric Laurent1afeecb2014-05-14 08:52:28 -07006176{
Eric Laurenta121f902014-06-03 13:32:54 -07006177 mIndex = index;
6178 mUseInChannelMask = useInChannelMask;
Eric Laurent1afeecb2014-05-14 08:52:28 -07006179 memset(&mGain, 0, sizeof(struct audio_gain));
6180}
6181
Eric Laurenta121f902014-06-03 13:32:54 -07006182void AudioPolicyManager::AudioGain::getDefaultConfig(struct audio_gain_config *config)
6183{
6184 config->index = mIndex;
6185 config->mode = mGain.mode;
6186 config->channel_mask = mGain.channel_mask;
6187 if ((mGain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
6188 config->values[0] = mGain.default_value;
6189 } else {
6190 uint32_t numValues;
6191 if (mUseInChannelMask) {
6192 numValues = audio_channel_count_from_in_mask(mGain.channel_mask);
6193 } else {
6194 numValues = audio_channel_count_from_out_mask(mGain.channel_mask);
6195 }
6196 for (size_t i = 0; i < numValues; i++) {
6197 config->values[i] = mGain.default_value;
6198 }
6199 }
6200 if ((mGain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
6201 config->ramp_duration_ms = mGain.min_ramp_ms;
6202 }
6203}
6204
6205status_t AudioPolicyManager::AudioGain::checkConfig(const struct audio_gain_config *config)
6206{
6207 if ((config->mode & ~mGain.mode) != 0) {
6208 return BAD_VALUE;
6209 }
6210 if ((config->mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
6211 if ((config->values[0] < mGain.min_value) ||
6212 (config->values[0] > mGain.max_value)) {
6213 return BAD_VALUE;
6214 }
6215 } else {
6216 if ((config->channel_mask & ~mGain.channel_mask) != 0) {
6217 return BAD_VALUE;
6218 }
6219 uint32_t numValues;
6220 if (mUseInChannelMask) {
6221 numValues = audio_channel_count_from_in_mask(config->channel_mask);
6222 } else {
6223 numValues = audio_channel_count_from_out_mask(config->channel_mask);
6224 }
6225 for (size_t i = 0; i < numValues; i++) {
6226 if ((config->values[i] < mGain.min_value) ||
6227 (config->values[i] > mGain.max_value)) {
6228 return BAD_VALUE;
6229 }
6230 }
6231 }
6232 if ((config->mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
6233 if ((config->ramp_duration_ms < mGain.min_ramp_ms) ||
6234 (config->ramp_duration_ms > mGain.max_ramp_ms)) {
6235 return BAD_VALUE;
6236 }
6237 }
6238 return NO_ERROR;
6239}
6240
Eric Laurent1afeecb2014-05-14 08:52:28 -07006241void AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const
6242{
6243 const size_t SIZE = 256;
6244 char buffer[SIZE];
6245 String8 result;
6246
6247 snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
6248 result.append(buffer);
6249 snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
6250 result.append(buffer);
6251 snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
6252 result.append(buffer);
6253 snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
6254 result.append(buffer);
6255 snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
6256 result.append(buffer);
6257 snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
6258 result.append(buffer);
6259 snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
6260 result.append(buffer);
6261 snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
6262 result.append(buffer);
6263 snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
6264 result.append(buffer);
6265
6266 write(fd, result.string(), result.size());
6267}
6268
Eric Laurent1f2f2232014-06-02 12:01:23 -07006269// --- AudioPortConfig class implementation
6270
6271AudioPolicyManager::AudioPortConfig::AudioPortConfig()
6272{
6273 mSamplingRate = 0;
6274 mChannelMask = AUDIO_CHANNEL_NONE;
6275 mFormat = AUDIO_FORMAT_INVALID;
6276 mGain.index = -1;
6277}
6278
Eric Laurenta121f902014-06-03 13:32:54 -07006279status_t AudioPolicyManager::AudioPortConfig::applyAudioPortConfig(
6280 const struct audio_port_config *config,
6281 struct audio_port_config *backupConfig)
6282{
6283 struct audio_port_config localBackupConfig;
6284 status_t status = NO_ERROR;
6285
6286 localBackupConfig.config_mask = config->config_mask;
6287 toAudioPortConfig(&localBackupConfig);
6288
Marco Nelissen961ec212014-08-25 15:58:39 -07006289 sp<AudioPort> audioport = getAudioPort();
6290 if (audioport == 0) {
Eric Laurenta121f902014-06-03 13:32:54 -07006291 status = NO_INIT;
6292 goto exit;
6293 }
6294 if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
Marco Nelissen961ec212014-08-25 15:58:39 -07006295 status = audioport->checkExactSamplingRate(config->sample_rate);
Eric Laurenta121f902014-06-03 13:32:54 -07006296 if (status != NO_ERROR) {
6297 goto exit;
6298 }
6299 mSamplingRate = config->sample_rate;
6300 }
6301 if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
Marco Nelissen961ec212014-08-25 15:58:39 -07006302 status = audioport->checkExactChannelMask(config->channel_mask);
Eric Laurenta121f902014-06-03 13:32:54 -07006303 if (status != NO_ERROR) {
6304 goto exit;
6305 }
6306 mChannelMask = config->channel_mask;
6307 }
6308 if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
Marco Nelissen961ec212014-08-25 15:58:39 -07006309 status = audioport->checkFormat(config->format);
Eric Laurenta121f902014-06-03 13:32:54 -07006310 if (status != NO_ERROR) {
6311 goto exit;
6312 }
6313 mFormat = config->format;
6314 }
6315 if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
Marco Nelissen961ec212014-08-25 15:58:39 -07006316 status = audioport->checkGain(&config->gain, config->gain.index);
Eric Laurenta121f902014-06-03 13:32:54 -07006317 if (status != NO_ERROR) {
6318 goto exit;
6319 }
6320 mGain = config->gain;
6321 }
6322
6323exit:
6324 if (status != NO_ERROR) {
6325 applyAudioPortConfig(&localBackupConfig);
6326 }
6327 if (backupConfig != NULL) {
6328 *backupConfig = localBackupConfig;
6329 }
6330 return status;
6331}
6332
Eric Laurent1f2f2232014-06-02 12:01:23 -07006333void AudioPolicyManager::AudioPortConfig::toAudioPortConfig(
6334 struct audio_port_config *dstConfig,
6335 const struct audio_port_config *srcConfig) const
6336{
6337 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
6338 dstConfig->sample_rate = mSamplingRate;
6339 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) {
6340 dstConfig->sample_rate = srcConfig->sample_rate;
6341 }
6342 } else {
6343 dstConfig->sample_rate = 0;
6344 }
6345 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
6346 dstConfig->channel_mask = mChannelMask;
6347 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) {
6348 dstConfig->channel_mask = srcConfig->channel_mask;
6349 }
6350 } else {
6351 dstConfig->channel_mask = AUDIO_CHANNEL_NONE;
6352 }
6353 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
6354 dstConfig->format = mFormat;
6355 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) {
6356 dstConfig->format = srcConfig->format;
6357 }
6358 } else {
6359 dstConfig->format = AUDIO_FORMAT_INVALID;
6360 }
6361 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
6362 dstConfig->gain = mGain;
6363 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) {
6364 dstConfig->gain = srcConfig->gain;
6365 }
6366 } else {
6367 dstConfig->gain.index = -1;
6368 }
6369 if (dstConfig->gain.index != -1) {
6370 dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
6371 } else {
6372 dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
6373 }
6374}
6375
Eric Laurent1c333e22014-05-20 10:48:17 -07006376// --- IOProfile class implementation
6377
Eric Laurent1afeecb2014-05-14 08:52:28 -07006378AudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role,
Eric Laurent1f2f2232014-06-02 12:01:23 -07006379 const sp<HwModule>& module)
Eric Laurent1e693b52014-07-09 15:03:28 -07006380 : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module)
Eric Laurente552edb2014-03-10 17:42:56 -07006381{
6382}
6383
Eric Laurente0720872014-03-11 09:30:41 -07006384AudioPolicyManager::IOProfile::~IOProfile()
Eric Laurente552edb2014-03-10 17:42:56 -07006385{
6386}
6387
6388// checks if the IO profile is compatible with specified parameters.
6389// Sampling rate, format and channel mask must be specified in order to
6390// get a valid a match
Eric Laurente0720872014-03-11 09:30:41 -07006391bool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device,
Eric Laurente552edb2014-03-10 17:42:56 -07006392 uint32_t samplingRate,
Glenn Kastencbd48022014-07-24 13:46:44 -07006393 uint32_t *updatedSamplingRate,
Eric Laurente552edb2014-03-10 17:42:56 -07006394 audio_format_t format,
6395 audio_channel_mask_t channelMask,
6396 audio_output_flags_t flags) const
6397{
Glenn Kastencbd48022014-07-24 13:46:44 -07006398 const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE;
6399 const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK;
6400 ALOG_ASSERT(isPlaybackThread != isRecordThread);
Eric Laurente552edb2014-03-10 17:42:56 -07006401
Glenn Kastencbd48022014-07-24 13:46:44 -07006402 if ((mSupportedDevices.types() & device) != device) {
6403 return false;
6404 }
6405
6406 if (samplingRate == 0) {
Eric Laurente552edb2014-03-10 17:42:56 -07006407 return false;
Glenn Kastencbd48022014-07-24 13:46:44 -07006408 }
6409 uint32_t myUpdatedSamplingRate = samplingRate;
6410 if (isPlaybackThread && checkExactSamplingRate(samplingRate) != NO_ERROR) {
Eric Laurente552edb2014-03-10 17:42:56 -07006411 return false;
Glenn Kastencbd48022014-07-24 13:46:44 -07006412 }
6413 if (isRecordThread && checkCompatibleSamplingRate(samplingRate, &myUpdatedSamplingRate) !=
6414 NO_ERROR) {
Eric Laurente552edb2014-03-10 17:42:56 -07006415 return false;
Glenn Kastencbd48022014-07-24 13:46:44 -07006416 }
6417
6418 if (!audio_is_valid_format(format) || checkFormat(format) != NO_ERROR) {
6419 return false;
6420 }
6421
6422 if (isPlaybackThread && (!audio_is_output_channel(channelMask) ||
6423 checkExactChannelMask(channelMask) != NO_ERROR)) {
6424 return false;
6425 }
6426 if (isRecordThread && (!audio_is_input_channel(channelMask) ||
6427 checkCompatibleChannelMask(channelMask) != NO_ERROR)) {
6428 return false;
6429 }
6430
6431 if (isPlaybackThread && (mFlags & flags) != flags) {
6432 return false;
6433 }
6434 // The only input flag that is allowed to be different is the fast flag.
6435 // An existing fast stream is compatible with a normal track request.
6436 // An existing normal stream is compatible with a fast track request,
6437 // but the fast request will be denied by AudioFlinger and converted to normal track.
6438 if (isRecordThread && (((audio_input_flags_t) mFlags ^ (audio_input_flags_t) flags) &
6439 ~AUDIO_INPUT_FLAG_FAST)) {
6440 return false;
6441 }
6442
6443 if (updatedSamplingRate != NULL) {
6444 *updatedSamplingRate = myUpdatedSamplingRate;
6445 }
6446 return true;
Eric Laurente552edb2014-03-10 17:42:56 -07006447}
6448
Eric Laurente0720872014-03-11 09:30:41 -07006449void AudioPolicyManager::IOProfile::dump(int fd)
Eric Laurente552edb2014-03-10 17:42:56 -07006450{
6451 const size_t SIZE = 256;
6452 char buffer[SIZE];
6453 String8 result;
6454
Eric Laurent1afeecb2014-05-14 08:52:28 -07006455 AudioPort::dump(fd, 4);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006456
Eric Laurente552edb2014-03-10 17:42:56 -07006457 snprintf(buffer, SIZE, " - flags: 0x%04x\n", mFlags);
6458 result.append(buffer);
Eric Laurent1afeecb2014-05-14 08:52:28 -07006459 snprintf(buffer, SIZE, " - devices:\n");
6460 result.append(buffer);
Eric Laurente552edb2014-03-10 17:42:56 -07006461 write(fd, result.string(), result.size());
Eric Laurent1afeecb2014-05-14 08:52:28 -07006462 for (size_t i = 0; i < mSupportedDevices.size(); i++) {
6463 mSupportedDevices[i]->dump(fd, 6, i);
6464 }
Eric Laurente552edb2014-03-10 17:42:56 -07006465}
6466
Eric Laurentd4692962014-05-05 18:13:44 -07006467void AudioPolicyManager::IOProfile::log()
6468{
6469 const size_t SIZE = 256;
6470 char buffer[SIZE];
6471 String8 result;
6472
6473 ALOGV(" - sampling rates: ");
6474 for (size_t i = 0; i < mSamplingRates.size(); i++) {
6475 ALOGV(" %d", mSamplingRates[i]);
6476 }
6477
6478 ALOGV(" - channel masks: ");
6479 for (size_t i = 0; i < mChannelMasks.size(); i++) {
6480 ALOGV(" 0x%04x", mChannelMasks[i]);
6481 }
6482
6483 ALOGV(" - formats: ");
6484 for (size_t i = 0; i < mFormats.size(); i++) {
6485 ALOGV(" 0x%08x", mFormats[i]);
6486 }
6487
6488 ALOGV(" - devices: 0x%04x\n", mSupportedDevices.types());
6489 ALOGV(" - flags: 0x%04x\n", mFlags);
6490}
6491
6492
Eric Laurent3a4311c2014-03-17 12:00:47 -07006493// --- DeviceDescriptor implementation
Eric Laurente552edb2014-03-10 17:42:56 -07006494
Eric Laurent1f2f2232014-06-02 12:01:23 -07006495
6496AudioPolicyManager::DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) :
6497 AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
6498 audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
6499 AUDIO_PORT_ROLE_SOURCE,
6500 NULL),
Eric Laurent1e693b52014-07-09 15:03:28 -07006501 mDeviceType(type), mAddress(""), mId(0)
Eric Laurent1f2f2232014-06-02 12:01:23 -07006502{
Eric Laurenta121f902014-06-03 13:32:54 -07006503 if (mGains.size() > 0) {
6504 mGains[0]->getDefaultConfig(&mGain);
6505 }
Eric Laurent1f2f2232014-06-02 12:01:23 -07006506}
6507
Eric Laurent3a4311c2014-03-17 12:00:47 -07006508bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
Eric Laurente552edb2014-03-10 17:42:56 -07006509{
Eric Laurent3a4311c2014-03-17 12:00:47 -07006510 // Devices are considered equal if they:
6511 // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
6512 // - have the same address or one device does not specify the address
6513 // - have the same channel mask or one device does not specify the channel mask
Eric Laurent1c333e22014-05-20 10:48:17 -07006514 return (mDeviceType == other->mDeviceType) &&
Eric Laurent3a4311c2014-03-17 12:00:47 -07006515 (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
Eric Laurent2f8a36f2014-03-26 19:05:55 -07006516 (mChannelMask == 0 || other->mChannelMask == 0 ||
Eric Laurent3a4311c2014-03-17 12:00:47 -07006517 mChannelMask == other->mChannelMask);
6518}
6519
6520void AudioPolicyManager::DeviceVector::refreshTypes()
6521{
Eric Laurent1c333e22014-05-20 10:48:17 -07006522 mDeviceTypes = AUDIO_DEVICE_NONE;
Eric Laurent3a4311c2014-03-17 12:00:47 -07006523 for(size_t i = 0; i < size(); i++) {
Eric Laurent1c333e22014-05-20 10:48:17 -07006524 mDeviceTypes |= itemAt(i)->mDeviceType;
Eric Laurent3a4311c2014-03-17 12:00:47 -07006525 }
Eric Laurent1c333e22014-05-20 10:48:17 -07006526 ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006527}
6528
6529ssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
6530{
6531 for(size_t i = 0; i < size(); i++) {
6532 if (item->equals(itemAt(i))) {
6533 return i;
Eric Laurente552edb2014-03-10 17:42:56 -07006534 }
6535 }
Eric Laurent3a4311c2014-03-17 12:00:47 -07006536 return -1;
Eric Laurente552edb2014-03-10 17:42:56 -07006537}
6538
Eric Laurent3a4311c2014-03-17 12:00:47 -07006539ssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item)
Eric Laurente552edb2014-03-10 17:42:56 -07006540{
Eric Laurent3a4311c2014-03-17 12:00:47 -07006541 ssize_t ret = indexOf(item);
6542
6543 if (ret < 0) {
6544 ret = SortedVector::add(item);
6545 if (ret >= 0) {
6546 refreshTypes();
6547 }
6548 } else {
Eric Laurent1c333e22014-05-20 10:48:17 -07006549 ALOGW("DeviceVector::add device %08x already in", item->mDeviceType);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006550 ret = -1;
6551 }
6552 return ret;
Eric Laurente552edb2014-03-10 17:42:56 -07006553}
6554
Eric Laurent3a4311c2014-03-17 12:00:47 -07006555ssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item)
6556{
6557 size_t i;
6558 ssize_t ret = indexOf(item);
6559
6560 if (ret < 0) {
Eric Laurent1c333e22014-05-20 10:48:17 -07006561 ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006562 } else {
6563 ret = SortedVector::removeAt(ret);
6564 if (ret >= 0) {
6565 refreshTypes();
6566 }
6567 }
6568 return ret;
6569}
6570
6571void AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types)
6572{
6573 DeviceVector deviceList;
6574
6575 uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
6576 types &= ~role_bit;
6577
6578 while (types) {
6579 uint32_t i = 31 - __builtin_clz(types);
6580 uint32_t type = 1 << i;
6581 types &= ~type;
Eric Laurent1afeecb2014-05-14 08:52:28 -07006582 add(new DeviceDescriptor(String8(""), type | role_bit));
Eric Laurent3a4311c2014-03-17 12:00:47 -07006583 }
6584}
6585
Eric Laurent1afeecb2014-05-14 08:52:28 -07006586void AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name,
6587 const DeviceVector& declaredDevices)
6588{
6589 char *devName = strtok(name, "|");
6590 while (devName != NULL) {
6591 if (strlen(devName) != 0) {
6592 audio_devices_t type = stringToEnum(sDeviceNameToEnumTable,
6593 ARRAY_SIZE(sDeviceNameToEnumTable),
6594 devName);
6595 if (type != AUDIO_DEVICE_NONE) {
6596 add(new DeviceDescriptor(String8(""), type));
6597 } else {
6598 sp<DeviceDescriptor> deviceDesc =
6599 declaredDevices.getDeviceFromName(String8(devName));
6600 if (deviceDesc != 0) {
6601 add(deviceDesc);
6602 }
6603 }
6604 }
6605 devName = strtok(NULL, "|");
6606 }
6607}
6608
Eric Laurent1c333e22014-05-20 10:48:17 -07006609sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice(
6610 audio_devices_t type, String8 address) const
6611{
6612 sp<DeviceDescriptor> device;
6613 for (size_t i = 0; i < size(); i++) {
6614 if (itemAt(i)->mDeviceType == type) {
6615 device = itemAt(i);
6616 if (itemAt(i)->mAddress = address) {
6617 break;
6618 }
6619 }
6620 }
6621 ALOGV("DeviceVector::getDevice() for type %d address %s found %p",
6622 type, address.string(), device.get());
6623 return device;
6624}
6625
Eric Laurent6a94d692014-05-20 11:18:06 -07006626sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId(
6627 audio_port_handle_t id) const
6628{
6629 sp<DeviceDescriptor> device;
6630 for (size_t i = 0; i < size(); i++) {
Mark Salyzynbeb9e302014-06-18 16:33:15 -07006631 ALOGV("DeviceVector::getDeviceFromId(%d) itemAt(%zu)->mId %d", id, i, itemAt(i)->mId);
Eric Laurent6a94d692014-05-20 11:18:06 -07006632 if (itemAt(i)->mId == id) {
6633 device = itemAt(i);
6634 break;
6635 }
6636 }
6637 return device;
6638}
6639
Eric Laurent1c333e22014-05-20 10:48:17 -07006640AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType(
6641 audio_devices_t type) const
6642{
6643 DeviceVector devices;
6644 for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
6645 if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) {
6646 devices.add(itemAt(i));
6647 type &= ~itemAt(i)->mDeviceType;
6648 ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
6649 itemAt(i)->mDeviceType, itemAt(i).get());
6650 }
6651 }
6652 return devices;
6653}
6654
Jean-Michel Trivi0fb47752014-07-22 16:19:14 -07006655AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromTypeAddr(
6656 audio_devices_t type, String8 address) const
6657{
6658 DeviceVector devices;
6659 //ALOGV(" looking for device=%x, addr=%s", type, address.string());
6660 for (size_t i = 0; i < size(); i++) {
6661 //ALOGV(" at i=%d: device=%x, addr=%s",
6662 // i, itemAt(i)->mDeviceType, itemAt(i)->mAddress.string());
6663 if (itemAt(i)->mDeviceType == type) {
6664 if (itemAt(i)->mAddress == address) {
6665 //ALOGV(" found matching address %s", address.string());
6666 devices.add(itemAt(i));
6667 }
6668 }
6669 }
6670 return devices;
6671}
6672
Eric Laurent1afeecb2014-05-14 08:52:28 -07006673sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName(
6674 const String8& name) const
6675{
6676 sp<DeviceDescriptor> device;
6677 for (size_t i = 0; i < size(); i++) {
6678 if (itemAt(i)->mName == name) {
6679 device = itemAt(i);
6680 break;
6681 }
6682 }
6683 return device;
6684}
6685
Eric Laurent6a94d692014-05-20 11:18:06 -07006686void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(
6687 struct audio_port_config *dstConfig,
6688 const struct audio_port_config *srcConfig) const
Eric Laurent1c333e22014-05-20 10:48:17 -07006689{
Eric Laurent1f2f2232014-06-02 12:01:23 -07006690 dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK|AUDIO_PORT_CONFIG_GAIN;
6691 if (srcConfig != NULL) {
Eric Laurent84c70242014-06-23 08:46:27 -07006692 dstConfig->config_mask |= srcConfig->config_mask;
Eric Laurent1f2f2232014-06-02 12:01:23 -07006693 }
6694
6695 AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
6696
Eric Laurent6a94d692014-05-20 11:18:06 -07006697 dstConfig->id = mId;
6698 dstConfig->role = audio_is_output_device(mDeviceType) ?
Eric Laurent1c333e22014-05-20 10:48:17 -07006699 AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
Eric Laurent6a94d692014-05-20 11:18:06 -07006700 dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
Eric Laurent6a94d692014-05-20 11:18:06 -07006701 dstConfig->ext.device.type = mDeviceType;
6702 dstConfig->ext.device.hw_module = mModule->mHandle;
6703 strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
Eric Laurent1c333e22014-05-20 10:48:17 -07006704}
6705
6706void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
6707{
Eric Laurent83b88082014-06-20 18:31:16 -07006708 ALOGV("DeviceDescriptor::toAudioPort() handle %d type %x", mId, mDeviceType);
Eric Laurent1c333e22014-05-20 10:48:17 -07006709 AudioPort::toAudioPort(port);
6710 port->id = mId;
Eric Laurent6a94d692014-05-20 11:18:06 -07006711 toAudioPortConfig(&port->active_config);
Eric Laurent1c333e22014-05-20 10:48:17 -07006712 port->ext.device.type = mDeviceType;
Eric Laurent6a94d692014-05-20 11:18:06 -07006713 port->ext.device.hw_module = mModule->mHandle;
Eric Laurent1c333e22014-05-20 10:48:17 -07006714 strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
6715}
6716
Eric Laurent1afeecb2014-05-14 08:52:28 -07006717status_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const
Eric Laurent3a4311c2014-03-17 12:00:47 -07006718{
6719 const size_t SIZE = 256;
6720 char buffer[SIZE];
Eric Laurent1afeecb2014-05-14 08:52:28 -07006721 String8 result;
Eric Laurent3a4311c2014-03-17 12:00:47 -07006722
Eric Laurent1afeecb2014-05-14 08:52:28 -07006723 snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
6724 result.append(buffer);
6725 if (mId != 0) {
6726 snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
6727 result.append(buffer);
6728 }
6729 snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "",
6730 enumToString(sDeviceNameToEnumTable,
6731 ARRAY_SIZE(sDeviceNameToEnumTable),
6732 mDeviceType));
6733 result.append(buffer);
6734 if (mAddress.size() != 0) {
6735 snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
6736 result.append(buffer);
6737 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006738 write(fd, result.string(), result.size());
6739 AudioPort::dump(fd, spaces);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006740
6741 return NO_ERROR;
6742}
6743
Eric Laurent4d416952014-08-10 14:07:09 -07006744status_t AudioPolicyManager::AudioPatch::dump(int fd, int spaces, int index) const
6745{
6746 const size_t SIZE = 256;
6747 char buffer[SIZE];
6748 String8 result;
6749
6750
6751 snprintf(buffer, SIZE, "%*sAudio patch %d:\n", spaces, "", index+1);
6752 result.append(buffer);
6753 snprintf(buffer, SIZE, "%*s- handle: %2d\n", spaces, "", mHandle);
6754 result.append(buffer);
6755 snprintf(buffer, SIZE, "%*s- audio flinger handle: %2d\n", spaces, "", mAfPatchHandle);
6756 result.append(buffer);
6757 snprintf(buffer, SIZE, "%*s- owner uid: %2d\n", spaces, "", mUid);
6758 result.append(buffer);
6759 snprintf(buffer, SIZE, "%*s- %d sources:\n", spaces, "", mPatch.num_sources);
6760 result.append(buffer);
6761 for (size_t i = 0; i < mPatch.num_sources; i++) {
6762 if (mPatch.sources[i].type == AUDIO_PORT_TYPE_DEVICE) {
6763 snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
6764 mPatch.sources[i].id, enumToString(sDeviceNameToEnumTable,
6765 ARRAY_SIZE(sDeviceNameToEnumTable),
6766 mPatch.sources[i].ext.device.type));
6767 } else {
6768 snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
6769 mPatch.sources[i].id, mPatch.sources[i].ext.mix.handle);
6770 }
6771 result.append(buffer);
6772 }
6773 snprintf(buffer, SIZE, "%*s- %d sinks:\n", spaces, "", mPatch.num_sinks);
6774 result.append(buffer);
6775 for (size_t i = 0; i < mPatch.num_sinks; i++) {
6776 if (mPatch.sinks[i].type == AUDIO_PORT_TYPE_DEVICE) {
6777 snprintf(buffer, SIZE, "%*s- Device ID %d %s\n", spaces + 2, "",
6778 mPatch.sinks[i].id, enumToString(sDeviceNameToEnumTable,
6779 ARRAY_SIZE(sDeviceNameToEnumTable),
6780 mPatch.sinks[i].ext.device.type));
6781 } else {
6782 snprintf(buffer, SIZE, "%*s- Mix ID %d I/O handle %d\n", spaces + 2, "",
6783 mPatch.sinks[i].id, mPatch.sinks[i].ext.mix.handle);
6784 }
6785 result.append(buffer);
6786 }
6787
6788 write(fd, result.string(), result.size());
6789 return NO_ERROR;
6790}
Eric Laurent3a4311c2014-03-17 12:00:47 -07006791
6792// --- audio_policy.conf file parsing
6793
Eric Laurente0720872014-03-11 09:30:41 -07006794audio_output_flags_t AudioPolicyManager::parseFlagNames(char *name)
Eric Laurente552edb2014-03-10 17:42:56 -07006795{
6796 uint32_t flag = 0;
6797
6798 // it is OK to cast name to non const here as we are not going to use it after
6799 // strtok() modifies it
6800 char *flagName = strtok(name, "|");
6801 while (flagName != NULL) {
6802 if (strlen(flagName) != 0) {
6803 flag |= stringToEnum(sFlagNameToEnumTable,
6804 ARRAY_SIZE(sFlagNameToEnumTable),
6805 flagName);
6806 }
6807 flagName = strtok(NULL, "|");
6808 }
6809 //force direct flag if offload flag is set: offloading implies a direct output stream
6810 // and all common behaviors are driven by checking only the direct flag
6811 // this should normally be set appropriately in the policy configuration file
6812 if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
6813 flag |= AUDIO_OUTPUT_FLAG_DIRECT;
6814 }
6815
6816 return (audio_output_flags_t)flag;
6817}
6818
Eric Laurente0720872014-03-11 09:30:41 -07006819audio_devices_t AudioPolicyManager::parseDeviceNames(char *name)
Eric Laurente552edb2014-03-10 17:42:56 -07006820{
6821 uint32_t device = 0;
6822
6823 char *devName = strtok(name, "|");
6824 while (devName != NULL) {
6825 if (strlen(devName) != 0) {
6826 device |= stringToEnum(sDeviceNameToEnumTable,
6827 ARRAY_SIZE(sDeviceNameToEnumTable),
6828 devName);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006829 }
Eric Laurente552edb2014-03-10 17:42:56 -07006830 devName = strtok(NULL, "|");
Eric Laurent3a4311c2014-03-17 12:00:47 -07006831 }
Eric Laurente552edb2014-03-10 17:42:56 -07006832 return device;
6833}
6834
Eric Laurente0720872014-03-11 09:30:41 -07006835void AudioPolicyManager::loadHwModule(cnode *root)
Eric Laurente552edb2014-03-10 17:42:56 -07006836{
Eric Laurente552edb2014-03-10 17:42:56 -07006837 status_t status = NAME_NOT_FOUND;
Eric Laurent1afeecb2014-05-14 08:52:28 -07006838 cnode *node;
Eric Laurent1f2f2232014-06-02 12:01:23 -07006839 sp<HwModule> module = new HwModule(root->name);
Eric Laurente552edb2014-03-10 17:42:56 -07006840
Eric Laurent1afeecb2014-05-14 08:52:28 -07006841 node = config_find(root, DEVICES_TAG);
6842 if (node != NULL) {
6843 node = node->first_child;
6844 while (node) {
6845 ALOGV("loadHwModule() loading device %s", node->name);
6846 status_t tmpStatus = module->loadDevice(node);
6847 if (status == NAME_NOT_FOUND || status == NO_ERROR) {
6848 status = tmpStatus;
6849 }
6850 node = node->next;
6851 }
6852 }
6853 node = config_find(root, OUTPUTS_TAG);
Eric Laurente552edb2014-03-10 17:42:56 -07006854 if (node != NULL) {
Eric Laurente552edb2014-03-10 17:42:56 -07006855 node = node->first_child;
6856 while (node) {
6857 ALOGV("loadHwModule() loading output %s", node->name);
Eric Laurent1afeecb2014-05-14 08:52:28 -07006858 status_t tmpStatus = module->loadOutput(node);
Eric Laurente552edb2014-03-10 17:42:56 -07006859 if (status == NAME_NOT_FOUND || status == NO_ERROR) {
6860 status = tmpStatus;
6861 }
6862 node = node->next;
6863 }
6864 }
6865 node = config_find(root, INPUTS_TAG);
6866 if (node != NULL) {
6867 node = node->first_child;
6868 while (node) {
6869 ALOGV("loadHwModule() loading input %s", node->name);
Eric Laurent1afeecb2014-05-14 08:52:28 -07006870 status_t tmpStatus = module->loadInput(node);
Eric Laurente552edb2014-03-10 17:42:56 -07006871 if (status == NAME_NOT_FOUND || status == NO_ERROR) {
6872 status = tmpStatus;
6873 }
6874 node = node->next;
6875 }
6876 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006877 loadGlobalConfig(root, module);
6878
Eric Laurente552edb2014-03-10 17:42:56 -07006879 if (status == NO_ERROR) {
6880 mHwModules.add(module);
Eric Laurente552edb2014-03-10 17:42:56 -07006881 }
6882}
6883
Eric Laurente0720872014-03-11 09:30:41 -07006884void AudioPolicyManager::loadHwModules(cnode *root)
Eric Laurente552edb2014-03-10 17:42:56 -07006885{
6886 cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
6887 if (node == NULL) {
6888 return;
6889 }
6890
6891 node = node->first_child;
6892 while (node) {
6893 ALOGV("loadHwModules() loading module %s", node->name);
6894 loadHwModule(node);
6895 node = node->next;
6896 }
6897}
6898
Eric Laurent1f2f2232014-06-02 12:01:23 -07006899void AudioPolicyManager::loadGlobalConfig(cnode *root, const sp<HwModule>& module)
Eric Laurente552edb2014-03-10 17:42:56 -07006900{
6901 cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
Eric Laurenteb108a42014-06-06 14:56:52 -07006902
Eric Laurente552edb2014-03-10 17:42:56 -07006903 if (node == NULL) {
6904 return;
6905 }
Eric Laurent1afeecb2014-05-14 08:52:28 -07006906 DeviceVector declaredDevices;
6907 if (module != NULL) {
6908 declaredDevices = module->mDeclaredDevices;
6909 }
6910
Eric Laurente552edb2014-03-10 17:42:56 -07006911 node = node->first_child;
6912 while (node) {
6913 if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07006914 mAvailableOutputDevices.loadDevicesFromName((char *)node->value,
6915 declaredDevices);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006916 ALOGV("loadGlobalConfig() Attached Output Devices %08x",
6917 mAvailableOutputDevices.types());
Eric Laurente552edb2014-03-10 17:42:56 -07006918 } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
Eric Laurent3a4311c2014-03-17 12:00:47 -07006919 audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,
Eric Laurente552edb2014-03-10 17:42:56 -07006920 ARRAY_SIZE(sDeviceNameToEnumTable),
6921 (char *)node->value);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006922 if (device != AUDIO_DEVICE_NONE) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07006923 mDefaultOutputDevice = new DeviceDescriptor(String8(""), device);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006924 } else {
6925 ALOGW("loadGlobalConfig() default device not specified");
6926 }
Eric Laurent1c333e22014-05-20 10:48:17 -07006927 ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType);
Eric Laurente552edb2014-03-10 17:42:56 -07006928 } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {
Eric Laurent1afeecb2014-05-14 08:52:28 -07006929 mAvailableInputDevices.loadDevicesFromName((char *)node->value,
6930 declaredDevices);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006931 ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types());
Eric Laurente552edb2014-03-10 17:42:56 -07006932 } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
6933 mSpeakerDrcEnabled = stringToBool((char *)node->value);
6934 ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);
Eric Laurenteb108a42014-06-06 14:56:52 -07006935 } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) {
6936 uint32_t major, minor;
6937 sscanf((char *)node->value, "%u.%u", &major, &minor);
6938 module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor);
6939 ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u",
6940 module->mHalVersion, major, minor);
Eric Laurente552edb2014-03-10 17:42:56 -07006941 }
6942 node = node->next;
6943 }
6944}
6945
Eric Laurente0720872014-03-11 09:30:41 -07006946status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
Eric Laurente552edb2014-03-10 17:42:56 -07006947{
6948 cnode *root;
6949 char *data;
6950
6951 data = (char *)load_file(path, NULL);
6952 if (data == NULL) {
6953 return -ENODEV;
6954 }
6955 root = config_node("", "");
6956 config_load(root, data);
6957
Eric Laurente552edb2014-03-10 17:42:56 -07006958 loadHwModules(root);
Eric Laurent1afeecb2014-05-14 08:52:28 -07006959 // legacy audio_policy.conf files have one global_configuration section
6960 loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY));
Eric Laurente552edb2014-03-10 17:42:56 -07006961 config_free(root);
6962 free(root);
6963 free(data);
6964
6965 ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
6966
6967 return NO_ERROR;
6968}
6969
Eric Laurente0720872014-03-11 09:30:41 -07006970void AudioPolicyManager::defaultAudioPolicyConfig(void)
Eric Laurente552edb2014-03-10 17:42:56 -07006971{
Eric Laurent1f2f2232014-06-02 12:01:23 -07006972 sp<HwModule> module;
Eric Laurent1c333e22014-05-20 10:48:17 -07006973 sp<IOProfile> profile;
Eric Laurent1f2f2232014-06-02 12:01:23 -07006974 sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""),
6975 AUDIO_DEVICE_IN_BUILTIN_MIC);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006976 mAvailableOutputDevices.add(mDefaultOutputDevice);
6977 mAvailableInputDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07006978
6979 module = new HwModule("primary");
6980
Eric Laurent1afeecb2014-05-14 08:52:28 -07006981 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module);
Eric Laurente552edb2014-03-10 17:42:56 -07006982 profile->mSamplingRates.add(44100);
6983 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
6984 profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006985 profile->mSupportedDevices.add(mDefaultOutputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07006986 profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
6987 module->mOutputProfiles.add(profile);
6988
Eric Laurent1afeecb2014-05-14 08:52:28 -07006989 profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module);
Eric Laurente552edb2014-03-10 17:42:56 -07006990 profile->mSamplingRates.add(8000);
6991 profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
6992 profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
Eric Laurent3a4311c2014-03-17 12:00:47 -07006993 profile->mSupportedDevices.add(defaultInputDevice);
Eric Laurente552edb2014-03-10 17:42:56 -07006994 module->mInputProfiles.add(profile);
6995
6996 mHwModules.add(module);
6997}
6998
Jean-Michel Trivi5bd3f382014-06-13 16:06:54 -07006999audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_attributes_t *attr)
7000{
7001 // flags to stream type mapping
7002 if ((attr->flags & AUDIO_FLAG_AUDIBILITY_ENFORCED) == AUDIO_FLAG_AUDIBILITY_ENFORCED) {
7003 return AUDIO_STREAM_ENFORCED_AUDIBLE;
7004 }
7005 if ((attr->flags & AUDIO_FLAG_SCO) == AUDIO_FLAG_SCO) {
7006 return AUDIO_STREAM_BLUETOOTH_SCO;
7007 }
7008
7009 // usage to stream type mapping
7010 switch (attr->usage) {
7011 case AUDIO_USAGE_MEDIA:
7012 case AUDIO_USAGE_GAME:
7013 case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
7014 case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
7015 return AUDIO_STREAM_MUSIC;
7016 case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
7017 return AUDIO_STREAM_SYSTEM;
7018 case AUDIO_USAGE_VOICE_COMMUNICATION:
7019 return AUDIO_STREAM_VOICE_CALL;
7020
7021 case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
7022 return AUDIO_STREAM_DTMF;
7023
7024 case AUDIO_USAGE_ALARM:
7025 return AUDIO_STREAM_ALARM;
7026 case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
7027 return AUDIO_STREAM_RING;
7028
7029 case AUDIO_USAGE_NOTIFICATION:
7030 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
7031 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
7032 case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
7033 case AUDIO_USAGE_NOTIFICATION_EVENT:
7034 return AUDIO_STREAM_NOTIFICATION;
7035
7036 case AUDIO_USAGE_UNKNOWN:
7037 default:
7038 return AUDIO_STREAM_MUSIC;
7039 }
7040}
Eric Laurente552edb2014-03-10 17:42:56 -07007041}; // namespace android