blob: 7cd253b72013efc1162a5bc0ee329392712c58b0 [file] [log] [blame]
Eric Laurent2d388ec2014-03-07 13:25:54 -08001/*
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 Laurentdce54a12014-03-10 12:19:46 -070017#define LOG_TAG "AudioPolicyIntefaceImpl"
Eric Laurent2d388ec2014-03-07 13:25:54 -080018//#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
21#include "AudioPolicyService.h"
22#include "ServiceUtilities.h"
23
Eric Laurent2d388ec2014-03-07 13:25:54 -080024namespace android {
25
26
27// ----------------------------------------------------------------------------
28
29status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
30 audio_policy_dev_state_t state,
31 const char *device_address)
32{
Eric Laurentdce54a12014-03-10 12:19:46 -070033 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -080034 return NO_INIT;
35 }
36 if (!settingsAllowed()) {
37 return PERMISSION_DENIED;
38 }
39 if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
40 return BAD_VALUE;
41 }
42 if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
43 state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
44 return BAD_VALUE;
45 }
46
47 ALOGV("setDeviceConnectionState()");
48 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -070049 return mAudioPolicyManager->setDeviceConnectionState(device,
Eric Laurent2d388ec2014-03-07 13:25:54 -080050 state, device_address);
51}
52
53audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
54 audio_devices_t device,
55 const char *device_address)
56{
Eric Laurentdce54a12014-03-10 12:19:46 -070057 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -080058 return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
59 }
Eric Laurentdce54a12014-03-10 12:19:46 -070060 return mAudioPolicyManager->getDeviceConnectionState(device,
Eric Laurent2d388ec2014-03-07 13:25:54 -080061 device_address);
62}
63
64status_t AudioPolicyService::setPhoneState(audio_mode_t state)
65{
Eric Laurentdce54a12014-03-10 12:19:46 -070066 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -080067 return NO_INIT;
68 }
69 if (!settingsAllowed()) {
70 return PERMISSION_DENIED;
71 }
72 if (uint32_t(state) >= AUDIO_MODE_CNT) {
73 return BAD_VALUE;
74 }
75
76 ALOGV("setPhoneState()");
77
78 // TODO: check if it is more appropriate to do it in platform specific policy manager
79 AudioSystem::setMode(state);
80
81 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -070082 mAudioPolicyManager->setPhoneState(state);
Eric Laurent2d388ec2014-03-07 13:25:54 -080083 return NO_ERROR;
84}
85
86status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
87 audio_policy_forced_cfg_t config)
88{
Eric Laurentdce54a12014-03-10 12:19:46 -070089 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -080090 return NO_INIT;
91 }
92 if (!settingsAllowed()) {
93 return PERMISSION_DENIED;
94 }
95 if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
96 return BAD_VALUE;
97 }
98 if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
99 return BAD_VALUE;
100 }
101 ALOGV("setForceUse()");
102 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700103 mAudioPolicyManager->setForceUse(usage, config);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800104 return NO_ERROR;
105}
106
107audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
108{
Eric Laurentdce54a12014-03-10 12:19:46 -0700109 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800110 return AUDIO_POLICY_FORCE_NONE;
111 }
112 if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
113 return AUDIO_POLICY_FORCE_NONE;
114 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700115 return mAudioPolicyManager->getForceUse(usage);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800116}
117
118audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
119 uint32_t samplingRate,
120 audio_format_t format,
121 audio_channel_mask_t channelMask,
122 audio_output_flags_t flags,
123 const audio_offload_info_t *offloadInfo)
124{
Eric Laurentdce54a12014-03-10 12:19:46 -0700125 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800126 return 0;
127 }
128 ALOGV("getOutput()");
129 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700130 return mAudioPolicyManager->getOutput(stream, samplingRate,
Eric Laurent2d388ec2014-03-07 13:25:54 -0800131 format, channelMask, flags, offloadInfo);
132}
133
134status_t AudioPolicyService::startOutput(audio_io_handle_t output,
135 audio_stream_type_t stream,
136 int session)
137{
Eric Laurentdce54a12014-03-10 12:19:46 -0700138 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800139 return NO_INIT;
140 }
141 ALOGV("startOutput()");
142 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700143 return mAudioPolicyManager->startOutput(output, stream, session);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800144}
145
146status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
147 audio_stream_type_t stream,
148 int session)
149{
Eric Laurentdce54a12014-03-10 12:19:46 -0700150 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800151 return NO_INIT;
152 }
153 ALOGV("stopOutput()");
154 mOutputCommandThread->stopOutputCommand(output, stream, session);
155 return NO_ERROR;
156}
157
158status_t AudioPolicyService::doStopOutput(audio_io_handle_t output,
159 audio_stream_type_t stream,
160 int session)
161{
162 ALOGV("doStopOutput from tid %d", gettid());
163 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700164 return mAudioPolicyManager->stopOutput(output, stream, session);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800165}
166
167void AudioPolicyService::releaseOutput(audio_io_handle_t output)
168{
Eric Laurentdce54a12014-03-10 12:19:46 -0700169 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800170 return;
171 }
172 ALOGV("releaseOutput()");
173 mOutputCommandThread->releaseOutputCommand(output);
174}
175
176void AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
177{
178 ALOGV("doReleaseOutput from tid %d", gettid());
179 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700180 mAudioPolicyManager->releaseOutput(output);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800181}
182
183audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
184 uint32_t samplingRate,
185 audio_format_t format,
186 audio_channel_mask_t channelMask,
187 int audioSession)
188{
Eric Laurentdce54a12014-03-10 12:19:46 -0700189 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800190 return 0;
191 }
192 // already checked by client, but double-check in case the client wrapper is bypassed
193 if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD) {
194 return 0;
195 }
196
197 if ((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
198 return 0;
199 }
200
201 Mutex::Autolock _l(mLock);
202 // the audio_in_acoustics_t parameter is ignored by get_input()
Eric Laurentdce54a12014-03-10 12:19:46 -0700203 audio_io_handle_t input = mAudioPolicyManager->getInput(inputSource, samplingRate,
Eric Laurent2d388ec2014-03-07 13:25:54 -0800204 format, channelMask, (audio_in_acoustics_t) 0);
205
206 if (input == 0) {
207 return input;
208 }
209 // create audio pre processors according to input source
210 audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
211 AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
212
213 ssize_t index = mInputSources.indexOfKey(aliasSource);
214 if (index < 0) {
215 return input;
216 }
217 ssize_t idx = mInputs.indexOfKey(input);
218 InputDesc *inputDesc;
219 if (idx < 0) {
220 inputDesc = new InputDesc(audioSession);
221 mInputs.add(input, inputDesc);
222 } else {
223 inputDesc = mInputs.valueAt(idx);
224 }
225
226 Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
227 for (size_t i = 0; i < effects.size(); i++) {
228 EffectDesc *effect = effects[i];
229 sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
230 status_t status = fx->initCheck();
231 if (status != NO_ERROR && status != ALREADY_EXISTS) {
232 ALOGW("Failed to create Fx %s on input %d", effect->mName, input);
233 // fx goes out of scope and strong ref on AudioEffect is released
234 continue;
235 }
236 for (size_t j = 0; j < effect->mParams.size(); j++) {
237 fx->setParameter(effect->mParams[j]);
238 }
239 inputDesc->mEffects.add(fx);
240 }
241 setPreProcessorEnabled(inputDesc, true);
242 return input;
243}
244
245status_t AudioPolicyService::startInput(audio_io_handle_t input)
246{
Eric Laurentdce54a12014-03-10 12:19:46 -0700247 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800248 return NO_INIT;
249 }
250 Mutex::Autolock _l(mLock);
251
Eric Laurentdce54a12014-03-10 12:19:46 -0700252 return mAudioPolicyManager->startInput(input);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800253}
254
255status_t AudioPolicyService::stopInput(audio_io_handle_t input)
256{
Eric Laurentdce54a12014-03-10 12:19:46 -0700257 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800258 return NO_INIT;
259 }
260 Mutex::Autolock _l(mLock);
261
Eric Laurentdce54a12014-03-10 12:19:46 -0700262 return mAudioPolicyManager->stopInput(input);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800263}
264
265void AudioPolicyService::releaseInput(audio_io_handle_t input)
266{
Eric Laurentdce54a12014-03-10 12:19:46 -0700267 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800268 return;
269 }
270 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700271 mAudioPolicyManager->releaseInput(input);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800272
273 ssize_t index = mInputs.indexOfKey(input);
274 if (index < 0) {
275 return;
276 }
277 InputDesc *inputDesc = mInputs.valueAt(index);
278 setPreProcessorEnabled(inputDesc, false);
279 delete inputDesc;
280 mInputs.removeItemsAt(index);
281}
282
283status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
284 int indexMin,
285 int indexMax)
286{
Eric Laurentdce54a12014-03-10 12:19:46 -0700287 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800288 return NO_INIT;
289 }
290 if (!settingsAllowed()) {
291 return PERMISSION_DENIED;
292 }
293 if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
294 return BAD_VALUE;
295 }
296 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700297 mAudioPolicyManager->initStreamVolume(stream, indexMin, indexMax);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800298 return NO_ERROR;
299}
300
301status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
302 int index,
303 audio_devices_t device)
304{
Eric Laurentdce54a12014-03-10 12:19:46 -0700305 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800306 return NO_INIT;
307 }
308 if (!settingsAllowed()) {
309 return PERMISSION_DENIED;
310 }
311 if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
312 return BAD_VALUE;
313 }
314 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700315 return mAudioPolicyManager->setStreamVolumeIndex(stream,
316 index,
317 device);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800318}
319
320status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
321 int *index,
322 audio_devices_t device)
323{
Eric Laurentdce54a12014-03-10 12:19:46 -0700324 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800325 return NO_INIT;
326 }
327 if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
328 return BAD_VALUE;
329 }
330 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700331 return mAudioPolicyManager->getStreamVolumeIndex(stream,
332 index,
333 device);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800334}
335
336uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
337{
Eric Laurentdce54a12014-03-10 12:19:46 -0700338 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800339 return 0;
340 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700341 return mAudioPolicyManager->getStrategyForStream(stream);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800342}
343
344//audio policy: use audio_device_t appropriately
345
346audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
347{
Eric Laurentdce54a12014-03-10 12:19:46 -0700348 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800349 return (audio_devices_t)0;
350 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700351 return mAudioPolicyManager->getDevicesForStream(stream);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800352}
353
354audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
355{
356 // FIXME change return type to status_t, and return NO_INIT here
Eric Laurentdce54a12014-03-10 12:19:46 -0700357 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800358 return 0;
359 }
360 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700361 return mAudioPolicyManager->getOutputForEffect(desc);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800362}
363
364status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
365 audio_io_handle_t io,
366 uint32_t strategy,
367 int session,
368 int id)
369{
Eric Laurentdce54a12014-03-10 12:19:46 -0700370 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800371 return NO_INIT;
372 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700373 return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800374}
375
376status_t AudioPolicyService::unregisterEffect(int id)
377{
Eric Laurentdce54a12014-03-10 12:19:46 -0700378 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800379 return NO_INIT;
380 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700381 return mAudioPolicyManager->unregisterEffect(id);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800382}
383
384status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
385{
Eric Laurentdce54a12014-03-10 12:19:46 -0700386 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800387 return NO_INIT;
388 }
Eric Laurentdce54a12014-03-10 12:19:46 -0700389 return mAudioPolicyManager->setEffectEnabled(id, enabled);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800390}
391
392bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
393{
Eric Laurentdce54a12014-03-10 12:19:46 -0700394 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800395 return 0;
396 }
397 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700398 return mAudioPolicyManager->isStreamActive(stream, inPastMs);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800399}
400
401bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
402{
Eric Laurentdce54a12014-03-10 12:19:46 -0700403 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800404 return 0;
405 }
406 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700407 return mAudioPolicyManager->isStreamActiveRemotely(stream, inPastMs);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800408}
409
410bool AudioPolicyService::isSourceActive(audio_source_t source) const
411{
Eric Laurentdce54a12014-03-10 12:19:46 -0700412 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800413 return false;
414 }
415 Mutex::Autolock _l(mLock);
Eric Laurentdce54a12014-03-10 12:19:46 -0700416 return mAudioPolicyManager->isSourceActive(source);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800417}
418
419status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
420 effect_descriptor_t *descriptors,
421 uint32_t *count)
422{
423
Eric Laurentdce54a12014-03-10 12:19:46 -0700424 if (mAudioPolicyManager == NULL) {
Eric Laurent2d388ec2014-03-07 13:25:54 -0800425 *count = 0;
426 return NO_INIT;
427 }
428 Mutex::Autolock _l(mLock);
429 status_t status = NO_ERROR;
430
431 size_t index;
432 for (index = 0; index < mInputs.size(); index++) {
433 if (mInputs.valueAt(index)->mSessionId == audioSession) {
434 break;
435 }
436 }
437 if (index == mInputs.size()) {
438 *count = 0;
439 return BAD_VALUE;
440 }
441 Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
442
443 for (size_t i = 0; i < effects.size(); i++) {
444 effect_descriptor_t desc = effects[i]->descriptor();
445 if (i < *count) {
446 descriptors[i] = desc;
447 }
448 }
449 if (effects.size() > *count) {
450 status = NO_MEMORY;
451 }
452 *count = effects.size();
453 return status;
454}
455
456bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
457{
Eric Laurentdce54a12014-03-10 12:19:46 -0700458 if (mAudioPolicyManager == NULL) {
459 ALOGV("mAudioPolicyManager == NULL");
Eric Laurent2d388ec2014-03-07 13:25:54 -0800460 return false;
461 }
462
Eric Laurentdce54a12014-03-10 12:19:46 -0700463 return mAudioPolicyManager->isOffloadSupported(info);
Eric Laurent2d388ec2014-03-07 13:25:54 -0800464}
465
Eric Laurent8670c312014-04-01 10:34:16 -0700466status_t AudioPolicyService::listAudioPorts(audio_port_role_t role __unused,
467 audio_port_type_t type __unused,
468 unsigned int *num_ports,
469 struct audio_port *ports __unused,
470 unsigned int *generation __unused)
471{
472 *num_ports = 0;
473 return INVALID_OPERATION;
474}
475
476status_t AudioPolicyService::getAudioPort(struct audio_port *port __unused)
477{
478 return INVALID_OPERATION;
479}
480
481status_t AudioPolicyService::createAudioPatch(const struct audio_patch *patch __unused,
482 audio_patch_handle_t *handle __unused)
483{
484 return INVALID_OPERATION;
485}
486
487status_t AudioPolicyService::releaseAudioPatch(audio_patch_handle_t handle __unused)
488{
489 return INVALID_OPERATION;
490}
491
492status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches,
493 struct audio_patch *patches __unused,
494 unsigned int *generation __unused)
495{
496 *num_patches = 0;
497 return INVALID_OPERATION;
498}
499
500status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *config __unused)
501{
502 return INVALID_OPERATION;
503}
Eric Laurent2d388ec2014-03-07 13:25:54 -0800504
505}; // namespace android