AudioPolicyInterfaceImpl.cpp revision 2d388eccc9dc085337c7a03a68467cbee6b809e1
1/*
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
17#define LOG_TAG "AudioPolicyService"
18//#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
21#include "AudioPolicyService.h"
22#include "ServiceUtilities.h"
23
24#include <system/audio.h>
25#include <system/audio_policy.h>
26#include <hardware/audio_policy.h>
27
28namespace android {
29
30
31// ----------------------------------------------------------------------------
32
33status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
34                                                  audio_policy_dev_state_t state,
35                                                  const char *device_address)
36{
37    if (mpAudioPolicy == NULL) {
38        return NO_INIT;
39    }
40    if (!settingsAllowed()) {
41        return PERMISSION_DENIED;
42    }
43    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
44        return BAD_VALUE;
45    }
46    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
47            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
48        return BAD_VALUE;
49    }
50
51    ALOGV("setDeviceConnectionState()");
52    Mutex::Autolock _l(mLock);
53    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
54                                                      state, device_address);
55}
56
57audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
58                                                              audio_devices_t device,
59                                                              const char *device_address)
60{
61    if (mpAudioPolicy == NULL) {
62        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
63    }
64    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
65                                                      device_address);
66}
67
68status_t AudioPolicyService::setPhoneState(audio_mode_t state)
69{
70    if (mpAudioPolicy == NULL) {
71        return NO_INIT;
72    }
73    if (!settingsAllowed()) {
74        return PERMISSION_DENIED;
75    }
76    if (uint32_t(state) >= AUDIO_MODE_CNT) {
77        return BAD_VALUE;
78    }
79
80    ALOGV("setPhoneState()");
81
82    // TODO: check if it is more appropriate to do it in platform specific policy manager
83    AudioSystem::setMode(state);
84
85    Mutex::Autolock _l(mLock);
86    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
87    return NO_ERROR;
88}
89
90status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
91                                         audio_policy_forced_cfg_t config)
92{
93    if (mpAudioPolicy == NULL) {
94        return NO_INIT;
95    }
96    if (!settingsAllowed()) {
97        return PERMISSION_DENIED;
98    }
99    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
100        return BAD_VALUE;
101    }
102    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
103        return BAD_VALUE;
104    }
105    ALOGV("setForceUse()");
106    Mutex::Autolock _l(mLock);
107    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
108    return NO_ERROR;
109}
110
111audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
112{
113    if (mpAudioPolicy == NULL) {
114        return AUDIO_POLICY_FORCE_NONE;
115    }
116    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
117        return AUDIO_POLICY_FORCE_NONE;
118    }
119    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
120}
121
122audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
123                                    uint32_t samplingRate,
124                                    audio_format_t format,
125                                    audio_channel_mask_t channelMask,
126                                    audio_output_flags_t flags,
127                                    const audio_offload_info_t *offloadInfo)
128{
129    if (mpAudioPolicy == NULL) {
130        return 0;
131    }
132    ALOGV("getOutput()");
133    Mutex::Autolock _l(mLock);
134    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate,
135                                    format, channelMask, flags, offloadInfo);
136}
137
138status_t AudioPolicyService::startOutput(audio_io_handle_t output,
139                                         audio_stream_type_t stream,
140                                         int session)
141{
142    if (mpAudioPolicy == NULL) {
143        return NO_INIT;
144    }
145    ALOGV("startOutput()");
146    Mutex::Autolock _l(mLock);
147    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
148}
149
150status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
151                                        audio_stream_type_t stream,
152                                        int session)
153{
154    if (mpAudioPolicy == NULL) {
155        return NO_INIT;
156    }
157    ALOGV("stopOutput()");
158    mOutputCommandThread->stopOutputCommand(output, stream, session);
159    return NO_ERROR;
160}
161
162status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
163                                      audio_stream_type_t stream,
164                                      int session)
165{
166    ALOGV("doStopOutput from tid %d", gettid());
167    Mutex::Autolock _l(mLock);
168    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
169}
170
171void AudioPolicyService::releaseOutput(audio_io_handle_t output)
172{
173    if (mpAudioPolicy == NULL) {
174        return;
175    }
176    ALOGV("releaseOutput()");
177    mOutputCommandThread->releaseOutputCommand(output);
178}
179
180void AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
181{
182    ALOGV("doReleaseOutput from tid %d", gettid());
183    Mutex::Autolock _l(mLock);
184    mpAudioPolicy->release_output(mpAudioPolicy, output);
185}
186
187audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
188                                    uint32_t samplingRate,
189                                    audio_format_t format,
190                                    audio_channel_mask_t channelMask,
191                                    int audioSession)
192{
193    if (mpAudioPolicy == NULL) {
194        return 0;
195    }
196    // already checked by client, but double-check in case the client wrapper is bypassed
197    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD) {
198        return 0;
199    }
200
201    if ((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
202        return 0;
203    }
204
205    Mutex::Autolock _l(mLock);
206    // the audio_in_acoustics_t parameter is ignored by get_input()
207    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
208                                                   format, channelMask, (audio_in_acoustics_t) 0);
209
210    if (input == 0) {
211        return input;
212    }
213    // create audio pre processors according to input source
214    audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
215                                    AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
216
217    ssize_t index = mInputSources.indexOfKey(aliasSource);
218    if (index < 0) {
219        return input;
220    }
221    ssize_t idx = mInputs.indexOfKey(input);
222    InputDesc *inputDesc;
223    if (idx < 0) {
224        inputDesc = new InputDesc(audioSession);
225        mInputs.add(input, inputDesc);
226    } else {
227        inputDesc = mInputs.valueAt(idx);
228    }
229
230    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
231    for (size_t i = 0; i < effects.size(); i++) {
232        EffectDesc *effect = effects[i];
233        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
234        status_t status = fx->initCheck();
235        if (status != NO_ERROR && status != ALREADY_EXISTS) {
236            ALOGW("Failed to create Fx %s on input %d", effect->mName, input);
237            // fx goes out of scope and strong ref on AudioEffect is released
238            continue;
239        }
240        for (size_t j = 0; j < effect->mParams.size(); j++) {
241            fx->setParameter(effect->mParams[j]);
242        }
243        inputDesc->mEffects.add(fx);
244    }
245    setPreProcessorEnabled(inputDesc, true);
246    return input;
247}
248
249status_t AudioPolicyService::startInput(audio_io_handle_t input)
250{
251    if (mpAudioPolicy == NULL) {
252        return NO_INIT;
253    }
254    Mutex::Autolock _l(mLock);
255
256    return mpAudioPolicy->start_input(mpAudioPolicy, input);
257}
258
259status_t AudioPolicyService::stopInput(audio_io_handle_t input)
260{
261    if (mpAudioPolicy == NULL) {
262        return NO_INIT;
263    }
264    Mutex::Autolock _l(mLock);
265
266    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
267}
268
269void AudioPolicyService::releaseInput(audio_io_handle_t input)
270{
271    if (mpAudioPolicy == NULL) {
272        return;
273    }
274    Mutex::Autolock _l(mLock);
275    mpAudioPolicy->release_input(mpAudioPolicy, input);
276
277    ssize_t index = mInputs.indexOfKey(input);
278    if (index < 0) {
279        return;
280    }
281    InputDesc *inputDesc = mInputs.valueAt(index);
282    setPreProcessorEnabled(inputDesc, false);
283    delete inputDesc;
284    mInputs.removeItemsAt(index);
285}
286
287status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
288                                            int indexMin,
289                                            int indexMax)
290{
291    if (mpAudioPolicy == NULL) {
292        return NO_INIT;
293    }
294    if (!settingsAllowed()) {
295        return PERMISSION_DENIED;
296    }
297    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
298        return BAD_VALUE;
299    }
300    Mutex::Autolock _l(mLock);
301    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
302    return NO_ERROR;
303}
304
305status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
306                                                  int index,
307                                                  audio_devices_t device)
308{
309    if (mpAudioPolicy == NULL) {
310        return NO_INIT;
311    }
312    if (!settingsAllowed()) {
313        return PERMISSION_DENIED;
314    }
315    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
316        return BAD_VALUE;
317    }
318    Mutex::Autolock _l(mLock);
319    if (mpAudioPolicy->set_stream_volume_index_for_device) {
320        return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
321                                                                stream,
322                                                                index,
323                                                                device);
324    } else {
325        return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
326    }
327}
328
329status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
330                                                  int *index,
331                                                  audio_devices_t device)
332{
333    if (mpAudioPolicy == NULL) {
334        return NO_INIT;
335    }
336    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
337        return BAD_VALUE;
338    }
339    Mutex::Autolock _l(mLock);
340    if (mpAudioPolicy->get_stream_volume_index_for_device) {
341        return mpAudioPolicy->get_stream_volume_index_for_device(mpAudioPolicy,
342                                                                stream,
343                                                                index,
344                                                                device);
345    } else {
346        return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
347    }
348}
349
350uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
351{
352    if (mpAudioPolicy == NULL) {
353        return 0;
354    }
355    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
356}
357
358//audio policy: use audio_device_t appropriately
359
360audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
361{
362    if (mpAudioPolicy == NULL) {
363        return (audio_devices_t)0;
364    }
365    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
366}
367
368audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
369{
370    // FIXME change return type to status_t, and return NO_INIT here
371    if (mpAudioPolicy == NULL) {
372        return 0;
373    }
374    Mutex::Autolock _l(mLock);
375    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
376}
377
378status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
379                                audio_io_handle_t io,
380                                uint32_t strategy,
381                                int session,
382                                int id)
383{
384    if (mpAudioPolicy == NULL) {
385        return NO_INIT;
386    }
387    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
388}
389
390status_t AudioPolicyService::unregisterEffect(int id)
391{
392    if (mpAudioPolicy == NULL) {
393        return NO_INIT;
394    }
395    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
396}
397
398status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
399{
400    if (mpAudioPolicy == NULL) {
401        return NO_INIT;
402    }
403    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
404}
405
406bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
407{
408    if (mpAudioPolicy == NULL) {
409        return 0;
410    }
411    Mutex::Autolock _l(mLock);
412    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
413}
414
415bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
416{
417    if (mpAudioPolicy == NULL) {
418        return 0;
419    }
420    Mutex::Autolock _l(mLock);
421    return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs);
422}
423
424bool AudioPolicyService::isSourceActive(audio_source_t source) const
425{
426    if (mpAudioPolicy == NULL) {
427        return false;
428    }
429    if (mpAudioPolicy->is_source_active == 0) {
430        return false;
431    }
432    Mutex::Autolock _l(mLock);
433    return mpAudioPolicy->is_source_active(mpAudioPolicy, source);
434}
435
436status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
437                                                       effect_descriptor_t *descriptors,
438                                                       uint32_t *count)
439{
440
441    if (mpAudioPolicy == NULL) {
442        *count = 0;
443        return NO_INIT;
444    }
445    Mutex::Autolock _l(mLock);
446    status_t status = NO_ERROR;
447
448    size_t index;
449    for (index = 0; index < mInputs.size(); index++) {
450        if (mInputs.valueAt(index)->mSessionId == audioSession) {
451            break;
452        }
453    }
454    if (index == mInputs.size()) {
455        *count = 0;
456        return BAD_VALUE;
457    }
458    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
459
460    for (size_t i = 0; i < effects.size(); i++) {
461        effect_descriptor_t desc = effects[i]->descriptor();
462        if (i < *count) {
463            descriptors[i] = desc;
464        }
465    }
466    if (effects.size() > *count) {
467        status = NO_MEMORY;
468    }
469    *count = effects.size();
470    return status;
471}
472
473bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
474{
475    if (mpAudioPolicy == NULL) {
476        ALOGV("mpAudioPolicy == NULL");
477        return false;
478    }
479
480    if (mpAudioPolicy->is_offload_supported == NULL) {
481        ALOGV("HAL does not implement is_offload_supported");
482        return false;
483    }
484
485    return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info);
486}
487
488
489}; // namespace android
490