AudioPolicyInterfaceImpl.cpp revision 97bb33f58d742539f3382583d7978fca71ffa2d5
10c1bc742181ded4930842b46e9507372f0b1b963James Dong/*
20c1bc742181ded4930842b46e9507372f0b1b963James Dong * Copyright (C) 2009 The Android Open Source Project
30c1bc742181ded4930842b46e9507372f0b1b963James Dong *
40c1bc742181ded4930842b46e9507372f0b1b963James Dong * Licensed under the Apache License, Version 2.0 (the "License");
50c1bc742181ded4930842b46e9507372f0b1b963James Dong * you may not use this file except in compliance with the License.
60c1bc742181ded4930842b46e9507372f0b1b963James Dong * You may obtain a copy of the License at
70c1bc742181ded4930842b46e9507372f0b1b963James Dong *
80c1bc742181ded4930842b46e9507372f0b1b963James Dong *      http://www.apache.org/licenses/LICENSE-2.0
90c1bc742181ded4930842b46e9507372f0b1b963James Dong *
100c1bc742181ded4930842b46e9507372f0b1b963James Dong * Unless required by applicable law or agreed to in writing, software
110c1bc742181ded4930842b46e9507372f0b1b963James Dong * distributed under the License is distributed on an "AS IS" BASIS,
120c1bc742181ded4930842b46e9507372f0b1b963James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130c1bc742181ded4930842b46e9507372f0b1b963James Dong * See the License for the specific language governing permissions and
140c1bc742181ded4930842b46e9507372f0b1b963James Dong * limitations under the License.
150c1bc742181ded4930842b46e9507372f0b1b963James Dong */
160c1bc742181ded4930842b46e9507372f0b1b963James Dong
170c1bc742181ded4930842b46e9507372f0b1b963James Dong#define LOG_TAG "AudioPolicyIntefaceImpl"
180c1bc742181ded4930842b46e9507372f0b1b963James Dong//#define LOG_NDEBUG 0
190c1bc742181ded4930842b46e9507372f0b1b963James Dong
200c1bc742181ded4930842b46e9507372f0b1b963James Dong#include <utils/Log.h>
210c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "AudioPolicyService.h"
220c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "ServiceUtilities.h"
230c1bc742181ded4930842b46e9507372f0b1b963James Dong
240c1bc742181ded4930842b46e9507372f0b1b963James Dongnamespace android {
250c1bc742181ded4930842b46e9507372f0b1b963James Dong
26457116d3a01618acf9a875020ca5860551ba03a6James Dong
270c1bc742181ded4930842b46e9507372f0b1b963James Dong// ----------------------------------------------------------------------------
280c1bc742181ded4930842b46e9507372f0b1b963James Dong
290c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
300c1bc742181ded4930842b46e9507372f0b1b963James Dong                                                  audio_policy_dev_state_t state,
31457116d3a01618acf9a875020ca5860551ba03a6James Dong                                                  const char *device_address)
32457116d3a01618acf9a875020ca5860551ba03a6James Dong{
33457116d3a01618acf9a875020ca5860551ba03a6James Dong    if (mAudioPolicyManager == NULL) {
34457116d3a01618acf9a875020ca5860551ba03a6James Dong        return NO_INIT;
35457116d3a01618acf9a875020ca5860551ba03a6James Dong    }
36457116d3a01618acf9a875020ca5860551ba03a6James Dong    if (!settingsAllowed()) {
37457116d3a01618acf9a875020ca5860551ba03a6James Dong        return PERMISSION_DENIED;
38457116d3a01618acf9a875020ca5860551ba03a6James Dong    }
39457116d3a01618acf9a875020ca5860551ba03a6James Dong    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
40457116d3a01618acf9a875020ca5860551ba03a6James Dong        return BAD_VALUE;
41457116d3a01618acf9a875020ca5860551ba03a6James Dong    }
42457116d3a01618acf9a875020ca5860551ba03a6James Dong    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
43457116d3a01618acf9a875020ca5860551ba03a6James Dong            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
44457116d3a01618acf9a875020ca5860551ba03a6James Dong        return BAD_VALUE;
45457116d3a01618acf9a875020ca5860551ba03a6James Dong    }
46457116d3a01618acf9a875020ca5860551ba03a6James Dong
47457116d3a01618acf9a875020ca5860551ba03a6James Dong    ALOGV("setDeviceConnectionState()");
48457116d3a01618acf9a875020ca5860551ba03a6James Dong    Mutex::Autolock _l(mLock);
49457116d3a01618acf9a875020ca5860551ba03a6James Dong    return mAudioPolicyManager->setDeviceConnectionState(device,
500c1bc742181ded4930842b46e9507372f0b1b963James Dong                                                      state, device_address);
510c1bc742181ded4930842b46e9507372f0b1b963James Dong}
520c1bc742181ded4930842b46e9507372f0b1b963James Dong
530c1bc742181ded4930842b46e9507372f0b1b963James Dongaudio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
540c1bc742181ded4930842b46e9507372f0b1b963James Dong                                                              audio_devices_t device,
557f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar                                                              const char *device_address)
567f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar{
577f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    if (mAudioPolicyManager == NULL) {
587f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
590c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
600c1bc742181ded4930842b46e9507372f0b1b963James Dong    return mAudioPolicyManager->getDeviceConnectionState(device,
610c1bc742181ded4930842b46e9507372f0b1b963James Dong                                                      device_address);
620c1bc742181ded4930842b46e9507372f0b1b963James Dong}
630c1bc742181ded4930842b46e9507372f0b1b963James Dong
640c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::setPhoneState(audio_mode_t state)
650c1bc742181ded4930842b46e9507372f0b1b963James Dong{
662961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber    if (mAudioPolicyManager == NULL) {
67a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        return NO_INIT;
68a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
697f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    if (!settingsAllowed()) {
70a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar        return PERMISSION_DENIED;
71a0940a569f2bc24b00dc10ce0fa7658b1dc3a3a5Lajos Molnar    }
727f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar    if (uint32_t(state) >= AUDIO_MODE_CNT) {
730c1bc742181ded4930842b46e9507372f0b1b963James Dong        return BAD_VALUE;
740c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
750c1bc742181ded4930842b46e9507372f0b1b963James Dong
760c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("setPhoneState()");
770c1bc742181ded4930842b46e9507372f0b1b963James Dong
780c1bc742181ded4930842b46e9507372f0b1b963James Dong    // TODO: check if it is more appropriate to do it in platform specific policy manager
790c1bc742181ded4930842b46e9507372f0b1b963James Dong    AudioSystem::setMode(state);
800c1bc742181ded4930842b46e9507372f0b1b963James Dong
810c1bc742181ded4930842b46e9507372f0b1b963James Dong    Mutex::Autolock _l(mLock);
820c1bc742181ded4930842b46e9507372f0b1b963James Dong    mAudioPolicyManager->setPhoneState(state);
830c1bc742181ded4930842b46e9507372f0b1b963James Dong    mPhoneState = state;
840c1bc742181ded4930842b46e9507372f0b1b963James Dong    return NO_ERROR;
850c1bc742181ded4930842b46e9507372f0b1b963James Dong}
860c1bc742181ded4930842b46e9507372f0b1b963James Dong
870c1bc742181ded4930842b46e9507372f0b1b963James Dongaudio_mode_t AudioPolicyService::getPhoneState()
880c1bc742181ded4930842b46e9507372f0b1b963James Dong{
890c1bc742181ded4930842b46e9507372f0b1b963James Dong    Mutex::Autolock _l(mLock);
900c1bc742181ded4930842b46e9507372f0b1b963James Dong    return mPhoneState;
910c1bc742181ded4930842b46e9507372f0b1b963James Dong}
920c1bc742181ded4930842b46e9507372f0b1b963James Dong
930c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
940c1bc742181ded4930842b46e9507372f0b1b963James Dong                                         audio_policy_forced_cfg_t config)
95486247017e0bfb9db9994a53a28c0dacfebf8567James Dong{
96486247017e0bfb9db9994a53a28c0dacfebf8567James Dong    if (mAudioPolicyManager == NULL) {
970c1bc742181ded4930842b46e9507372f0b1b963James Dong        return NO_INIT;
980c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
990c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (!settingsAllowed()) {
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong        return PERMISSION_DENIED;
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
10284333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
1032961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber        return BAD_VALUE;
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong        return BAD_VALUE;
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("setForceUse()");
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong    Mutex::Autolock _l(mLock);
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong    mAudioPolicyManager->setForceUse(usage, config);
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong    return NO_ERROR;
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1132309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber
1142309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huberaudio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
1152309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber{
1162309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber    if (mAudioPolicyManager == NULL) {
1172309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber        return AUDIO_POLICY_FORCE_NONE;
1182309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber    }
1192309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
1202309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber        return AUDIO_POLICY_FORCE_NONE;
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
122bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    return mAudioPolicyManager->getForceUse(usage);
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong
1250c1bc742181ded4930842b46e9507372f0b1b963James Dongaudio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong                                    uint32_t samplingRate,
1272309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                                    audio_format_t format,
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong                                    audio_channel_mask_t channelMask,
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong                                    audio_output_flags_t flags,
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong                                    const audio_offload_info_t *offloadInfo)
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong        return AUDIO_IO_HANDLE_NONE;
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (mAudioPolicyManager == NULL) {
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong        return AUDIO_IO_HANDLE_NONE;
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("getOutput()");
1394c44e9fed87ff6363393f2559b150291242da247Marco Nelissen    Mutex::Autolock _l(mLock);
1404c44e9fed87ff6363393f2559b150291242da247Marco Nelissen    return mAudioPolicyManager->getOutput(stream, samplingRate,
1414c44e9fed87ff6363393f2559b150291242da247Marco Nelissen                                    format, channelMask, flags, offloadInfo);
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong
1440c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_io_handle_t *output,
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_session_t session,
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_stream_type_t *stream,
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              uint32_t samplingRate,
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_format_t format,
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_channel_mask_t channelMask,
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              audio_output_flags_t flags,
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong                                              const audio_offload_info_t *offloadInfo)
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (mAudioPolicyManager == NULL) {
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong        return NO_INIT;
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("getOutput()");
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong    Mutex::Autolock _l(mLock);
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong    return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, samplingRate,
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong                                    format, channelMask, flags, offloadInfo);
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong
1630c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::startOutput(audio_io_handle_t output,
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong                                         audio_stream_type_t stream,
165d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu                                         audio_session_t session)
166d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu{
167bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
168bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        return BAD_VALUE;
169d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu    }
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (mAudioPolicyManager == NULL) {
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong        return NO_INIT;
172bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    }
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("startOutput()");
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong    sp<AudioPolicyEffects>audioPolicyEffects;
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong        Mutex::Autolock _l(mLock);
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong        audioPolicyEffects = mAudioPolicyEffects;
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (audioPolicyEffects != 0) {
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong        // create audio processors according to stream
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong        status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session);
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (status != NO_ERROR && status != ALREADY_EXISTS) {
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong            ALOGW("Failed to add effects on session %d", session);
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong    Mutex::Autolock _l(mLock);
18729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    return mAudioPolicyManager->startOutput(output, stream, session);
1882961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber}
1892961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber
1902961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huberstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output,
1912961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber                                        audio_stream_type_t stream,
1922961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber                                        audio_session_t session)
1932961a85f5f00343c115ac8e5dc17de631694fb6eAndreas Huber{
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong        return BAD_VALUE;
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (mAudioPolicyManager == NULL) {
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong        return NO_INIT;
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
200bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    ALOGV("stopOutput()");
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong    mOutputCommandThread->stopOutputCommand(output, stream, session);
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong    return NO_ERROR;
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong
2050c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      audio_stream_type_t stream,
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      audio_session_t session)
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong{
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong    ALOGV("doStopOutput from tid %d", gettid());
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong    sp<AudioPolicyEffects>audioPolicyEffects;
2112309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber    {
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong        Mutex::Autolock _l(mLock);
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong        audioPolicyEffects = mAudioPolicyEffects;
2140c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
215d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu    if (audioPolicyEffects != 0) {
216d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu        // release audio processors from the stream
217bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        status_t status = audioPolicyEffects->releaseOutputSessionEffects(output, stream, session);
218d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu        if (status != NO_ERROR && status != ALREADY_EXISTS) {
2190c1bc742181ded4930842b46e9507372f0b1b963James Dong            ALOGW("Failed to release effects on session %d", session);
2200c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
221bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    }
222bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    Mutex::Autolock _l(mLock);
223bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    return mAudioPolicyManager->stopOutput(output, stream, session);
224bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu}
225bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu
226d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wuvoid AudioPolicyService::releaseOutput(audio_io_handle_t output,
2270c1bc742181ded4930842b46e9507372f0b1b963James Dong                                       audio_stream_type_t stream,
228bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu                                       audio_session_t session)
229bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu{
230bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    if (mAudioPolicyManager == NULL) {
231bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        return;
232bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    }
233d5a2f55034022f2d0425fa0701894d0c4787b726Ronghua Wu    ALOGV("releaseOutput()");
2340c1bc742181ded4930842b46e9507372f0b1b963James Dong    mOutputCommandThread->releaseOutputCommand(output, stream, session);
2350c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2360c1bc742181ded4930842b46e9507372f0b1b963James Dong
2370c1bc742181ded4930842b46e9507372f0b1b963James Dongvoid AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
2380c1bc742181ded4930842b46e9507372f0b1b963James Dong                                         audio_stream_type_t stream,
2390c1bc742181ded4930842b46e9507372f0b1b963James Dong                                         audio_session_t session)
240bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu{
241bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    ALOGV("doReleaseOutput from tid %d", gettid());
242bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    Mutex::Autolock _l(mLock);
2430c1bc742181ded4930842b46e9507372f0b1b963James Dong    mAudioPolicyManager->releaseOutput(output, stream, session);
2440c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2450c1bc742181ded4930842b46e9507372f0b1b963James Dong
2460c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
2470c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             audio_io_handle_t *input,
2480c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             audio_session_t session,
2490c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             uint32_t samplingRate,
2500c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             audio_format_t format,
2510c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             audio_channel_mask_t channelMask,
2520c1bc742181ded4930842b46e9507372f0b1b963James Dong                                             audio_input_flags_t flags)
253bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu{
254bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    if (mAudioPolicyManager == NULL) {
255bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        return NO_INIT;
256bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    }
257bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    // already checked by client, but double-check in case the client wrapper is bypassed
258bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
259bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        attr->source != AUDIO_SOURCE_FM_TUNER) {
260bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu        return BAD_VALUE;
261bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    }
262bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu
263bf220f3e6e799f28d1599c3c5106e9e15631a91dRonghua Wu    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
2640c1bc742181ded4930842b46e9507372f0b1b963James Dong        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
2650c1bc742181ded4930842b46e9507372f0b1b963James Dong        return BAD_VALUE;
2660c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
2670c1bc742181ded4930842b46e9507372f0b1b963James Dong    sp<AudioPolicyEffects>audioPolicyEffects;
2680c1bc742181ded4930842b46e9507372f0b1b963James Dong    status_t status;
2690c1bc742181ded4930842b46e9507372f0b1b963James Dong    AudioPolicyInterface::input_type_t inputType;
2702309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber    {
2710c1bc742181ded4930842b46e9507372f0b1b963James Dong        Mutex::Autolock _l(mLock);
2720c1bc742181ded4930842b46e9507372f0b1b963James Dong        // the audio_in_acoustics_t parameter is ignored by get_input()
2730c1bc742181ded4930842b46e9507372f0b1b963James Dong        status = mAudioPolicyManager->getInputForAttr(attr, input, session,
2742309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                                                     samplingRate, format, channelMask,
2752309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                                                     flags, &inputType);
2762309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber        audioPolicyEffects = mAudioPolicyEffects;
2772309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber
2782309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber        if (status == NO_ERROR) {
2792309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber            // enforce permission (if any) required for each type of input
2802309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber            switch (inputType) {
2812309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber            case AudioPolicyInterface::API_INPUT_LEGACY:
2822309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                break;
2832309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber            case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
2842309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                if (!captureAudioOutputAllowed()) {
2852309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                    ALOGE("getInputForAttr() permission denied: capture not allowed");
2862309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                    status = PERMISSION_DENIED;
2872309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                }
2880c1bc742181ded4930842b46e9507372f0b1b963James Dong                break;
2890c1bc742181ded4930842b46e9507372f0b1b963James Dong            case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
2900c1bc742181ded4930842b46e9507372f0b1b963James Dong                if (!modifyAudioRoutingAllowed()) {
2910c1bc742181ded4930842b46e9507372f0b1b963James Dong                    ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
2920c1bc742181ded4930842b46e9507372f0b1b963James Dong                    status = PERMISSION_DENIED;
2932309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                }
2942309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber                break;
2952309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber            case AudioPolicyInterface::API_INPUT_INVALID:
2960c1bc742181ded4930842b46e9507372f0b1b963James Dong            default:
2970c1bc742181ded4930842b46e9507372f0b1b963James Dong                LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",
2980c1bc742181ded4930842b46e9507372f0b1b963James Dong                        (int)inputType);
2990c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3002309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber        }
3012309d1a1ff016a31d9aa68272bcb471e64a26cfaAndreas Huber
3020c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (status != NO_ERROR) {
3030c1bc742181ded4930842b46e9507372f0b1b963James Dong            if (status == PERMISSION_DENIED) {
3040c1bc742181ded4930842b46e9507372f0b1b963James Dong                mAudioPolicyManager->releaseInput(*input, session);
3050c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3060c1bc742181ded4930842b46e9507372f0b1b963James Dong            return status;
3070c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3080c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
3090c1bc742181ded4930842b46e9507372f0b1b963James Dong
310d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber    if (audioPolicyEffects != 0) {
3117f616d3cc5366a4b8af20d3d0c768e3de1df0666Lajos Molnar        // create audio pre processors according to input source
312d94e716af0e49d775f0c0c4f36dd2c136ba5f2b2Andreas Huber        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
3130c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (status != NO_ERROR && status != ALREADY_EXISTS) {
3140c1bc742181ded4930842b46e9507372f0b1b963James Dong            ALOGW("Failed to add effects on input %d", *input);
3150c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3160c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
3170c1bc742181ded4930842b46e9507372f0b1b963James Dong    return NO_ERROR;
3180c1bc742181ded4930842b46e9507372f0b1b963James Dong}
3190c1bc742181ded4930842b46e9507372f0b1b963James Dong
3200c1bc742181ded4930842b46e9507372f0b1b963James Dongstatus_t AudioPolicyService::startInput(audio_io_handle_t input,
3210c1bc742181ded4930842b46e9507372f0b1b963James Dong                                        audio_session_t session)
322{
323    if (mAudioPolicyManager == NULL) {
324        return NO_INIT;
325    }
326    Mutex::Autolock _l(mLock);
327
328    return mAudioPolicyManager->startInput(input, session);
329}
330
331status_t AudioPolicyService::stopInput(audio_io_handle_t input,
332                                       audio_session_t session)
333{
334    if (mAudioPolicyManager == NULL) {
335        return NO_INIT;
336    }
337    Mutex::Autolock _l(mLock);
338
339    return mAudioPolicyManager->stopInput(input, session);
340}
341
342void AudioPolicyService::releaseInput(audio_io_handle_t input,
343                                      audio_session_t session)
344{
345    if (mAudioPolicyManager == NULL) {
346        return;
347    }
348    sp<AudioPolicyEffects>audioPolicyEffects;
349    {
350        Mutex::Autolock _l(mLock);
351        mAudioPolicyManager->releaseInput(input, session);
352        audioPolicyEffects = mAudioPolicyEffects;
353    }
354    if (audioPolicyEffects != 0) {
355        // release audio processors from the input
356        status_t status = audioPolicyEffects->releaseInputEffects(input);
357        if(status != NO_ERROR) {
358            ALOGW("Failed to release effects on input %d", input);
359        }
360    }
361}
362
363status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
364                                            int indexMin,
365                                            int indexMax)
366{
367    if (mAudioPolicyManager == NULL) {
368        return NO_INIT;
369    }
370    if (!settingsAllowed()) {
371        return PERMISSION_DENIED;
372    }
373    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
374        return BAD_VALUE;
375    }
376    Mutex::Autolock _l(mLock);
377    mAudioPolicyManager->initStreamVolume(stream, indexMin, indexMax);
378    return NO_ERROR;
379}
380
381status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
382                                                  int index,
383                                                  audio_devices_t device)
384{
385    if (mAudioPolicyManager == NULL) {
386        return NO_INIT;
387    }
388    if (!settingsAllowed()) {
389        return PERMISSION_DENIED;
390    }
391    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
392        return BAD_VALUE;
393    }
394    Mutex::Autolock _l(mLock);
395    return mAudioPolicyManager->setStreamVolumeIndex(stream,
396                                                    index,
397                                                    device);
398}
399
400status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
401                                                  int *index,
402                                                  audio_devices_t device)
403{
404    if (mAudioPolicyManager == NULL) {
405        return NO_INIT;
406    }
407    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
408        return BAD_VALUE;
409    }
410    Mutex::Autolock _l(mLock);
411    return mAudioPolicyManager->getStreamVolumeIndex(stream,
412                                                    index,
413                                                    device);
414}
415
416uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
417{
418    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
419        return 0;
420    }
421    if (mAudioPolicyManager == NULL) {
422        return 0;
423    }
424    return mAudioPolicyManager->getStrategyForStream(stream);
425}
426
427//audio policy: use audio_device_t appropriately
428
429audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
430{
431    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
432        return AUDIO_DEVICE_NONE;
433    }
434    if (mAudioPolicyManager == NULL) {
435        return AUDIO_DEVICE_NONE;
436    }
437    return mAudioPolicyManager->getDevicesForStream(stream);
438}
439
440audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
441{
442    // FIXME change return type to status_t, and return NO_INIT here
443    if (mAudioPolicyManager == NULL) {
444        return 0;
445    }
446    Mutex::Autolock _l(mLock);
447    return mAudioPolicyManager->getOutputForEffect(desc);
448}
449
450status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
451                                audio_io_handle_t io,
452                                uint32_t strategy,
453                                int session,
454                                int id)
455{
456    if (mAudioPolicyManager == NULL) {
457        return NO_INIT;
458    }
459    return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
460}
461
462status_t AudioPolicyService::unregisterEffect(int id)
463{
464    if (mAudioPolicyManager == NULL) {
465        return NO_INIT;
466    }
467    return mAudioPolicyManager->unregisterEffect(id);
468}
469
470status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
471{
472    if (mAudioPolicyManager == NULL) {
473        return NO_INIT;
474    }
475    return mAudioPolicyManager->setEffectEnabled(id, enabled);
476}
477
478bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
479{
480    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
481        return false;
482    }
483    if (mAudioPolicyManager == NULL) {
484        return false;
485    }
486    Mutex::Autolock _l(mLock);
487    return mAudioPolicyManager->isStreamActive(stream, inPastMs);
488}
489
490bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
491{
492    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
493        return false;
494    }
495    if (mAudioPolicyManager == NULL) {
496        return false;
497    }
498    Mutex::Autolock _l(mLock);
499    return mAudioPolicyManager->isStreamActiveRemotely(stream, inPastMs);
500}
501
502bool AudioPolicyService::isSourceActive(audio_source_t source) const
503{
504    if (mAudioPolicyManager == NULL) {
505        return false;
506    }
507    Mutex::Autolock _l(mLock);
508    return mAudioPolicyManager->isSourceActive(source);
509}
510
511status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
512                                                       effect_descriptor_t *descriptors,
513                                                       uint32_t *count)
514{
515    if (mAudioPolicyManager == NULL) {
516        *count = 0;
517        return NO_INIT;
518    }
519    sp<AudioPolicyEffects>audioPolicyEffects;
520    {
521        Mutex::Autolock _l(mLock);
522        audioPolicyEffects = mAudioPolicyEffects;
523    }
524    if (audioPolicyEffects == 0) {
525        *count = 0;
526        return NO_INIT;
527    }
528    return audioPolicyEffects->queryDefaultInputEffects(audioSession, descriptors, count);
529}
530
531bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
532{
533    if (mAudioPolicyManager == NULL) {
534        ALOGV("mAudioPolicyManager == NULL");
535        return false;
536    }
537
538    return mAudioPolicyManager->isOffloadSupported(info);
539}
540
541status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
542                                            audio_port_type_t type,
543                                            unsigned int *num_ports,
544                                            struct audio_port *ports,
545                                            unsigned int *generation)
546{
547    Mutex::Autolock _l(mLock);
548    if(!modifyAudioRoutingAllowed()) {
549        return PERMISSION_DENIED;
550    }
551    if (mAudioPolicyManager == NULL) {
552        return NO_INIT;
553    }
554
555    return mAudioPolicyManager->listAudioPorts(role, type, num_ports, ports, generation);
556}
557
558status_t AudioPolicyService::getAudioPort(struct audio_port *port)
559{
560    Mutex::Autolock _l(mLock);
561    if(!modifyAudioRoutingAllowed()) {
562        return PERMISSION_DENIED;
563    }
564    if (mAudioPolicyManager == NULL) {
565        return NO_INIT;
566    }
567
568    return mAudioPolicyManager->getAudioPort(port);
569}
570
571status_t AudioPolicyService::createAudioPatch(const struct audio_patch *patch,
572        audio_patch_handle_t *handle)
573{
574    Mutex::Autolock _l(mLock);
575    if(!modifyAudioRoutingAllowed()) {
576        return PERMISSION_DENIED;
577    }
578    if (mAudioPolicyManager == NULL) {
579        return NO_INIT;
580    }
581    return mAudioPolicyManager->createAudioPatch(patch, handle,
582                                                  IPCThreadState::self()->getCallingUid());
583}
584
585status_t AudioPolicyService::releaseAudioPatch(audio_patch_handle_t handle)
586{
587    Mutex::Autolock _l(mLock);
588    if(!modifyAudioRoutingAllowed()) {
589        return PERMISSION_DENIED;
590    }
591    if (mAudioPolicyManager == NULL) {
592        return NO_INIT;
593    }
594
595    return mAudioPolicyManager->releaseAudioPatch(handle,
596                                                     IPCThreadState::self()->getCallingUid());
597}
598
599status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches,
600        struct audio_patch *patches,
601        unsigned int *generation)
602{
603    Mutex::Autolock _l(mLock);
604    if(!modifyAudioRoutingAllowed()) {
605        return PERMISSION_DENIED;
606    }
607    if (mAudioPolicyManager == NULL) {
608        return NO_INIT;
609    }
610
611    return mAudioPolicyManager->listAudioPatches(num_patches, patches, generation);
612}
613
614status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *config)
615{
616    Mutex::Autolock _l(mLock);
617    if(!modifyAudioRoutingAllowed()) {
618        return PERMISSION_DENIED;
619    }
620    if (mAudioPolicyManager == NULL) {
621        return NO_INIT;
622    }
623
624    return mAudioPolicyManager->setAudioPortConfig(config);
625}
626
627status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session,
628                                       audio_io_handle_t *ioHandle,
629                                       audio_devices_t *device)
630{
631    if (mAudioPolicyManager == NULL) {
632        return NO_INIT;
633    }
634
635    return mAudioPolicyManager->acquireSoundTriggerSession(session, ioHandle, device);
636}
637
638status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
639{
640    if (mAudioPolicyManager == NULL) {
641        return NO_INIT;
642    }
643
644    return mAudioPolicyManager->releaseSoundTriggerSession(session);
645}
646
647status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes, bool registration)
648{
649    Mutex::Autolock _l(mLock);
650    if(!modifyAudioRoutingAllowed()) {
651        return PERMISSION_DENIED;
652    }
653    if (mAudioPolicyManager == NULL) {
654        return NO_INIT;
655    }
656    if (registration) {
657        return mAudioPolicyManager->registerPolicyMixes(mixes);
658    } else {
659        return mAudioPolicyManager->unregisterPolicyMixes(mixes);
660    }
661}
662
663}; // namespace android
664