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