From 53615e29c99c5e9d2ca77aaefd7bf5c770513120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Gaffie?= Date: Thu, 19 Mar 2015 09:24:12 +0100 Subject: Migrate helper functions from managerdefault to common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch moves from manager to common: -parse helper functions of the policy configuration file -collection helper function on -output / input descriptors -DeviceDescriptor -AudioPatch / Audio Port -IO Profile -HwModule Change-Id: If45e53418db75af1af198f43c4ef27884499055f Signed-off-by: François Gaffie --- services/audiopolicy/Android.mk | 10 +- services/audiopolicy/common/include/policy.h | 84 +++ .../common/managerdefinitions/Android.mk | 1 + .../include/AudioInputDescriptor.h | 26 + .../include/AudioOutputDescriptor.h | 37 ++ .../common/managerdefinitions/include/AudioPatch.h | 14 + .../common/managerdefinitions/include/AudioPort.h | 11 +- .../include/ConfigParsingUtils.h | 36 +- .../managerdefinitions/include/DeviceDescriptor.h | 24 +- .../common/managerdefinitions/include/HwModule.h | 16 + .../src/AudioInputDescriptor.cpp | 87 ++- .../src/AudioOutputDescriptor.cpp | 118 +++- .../common/managerdefinitions/src/AudioPatch.cpp | 70 +++ .../common/managerdefinitions/src/AudioPort.cpp | 8 +- .../managerdefinitions/src/ConfigParsingUtils.cpp | 166 +++++ .../managerdefinitions/src/DeviceDescriptor.cpp | 53 +- .../common/managerdefinitions/src/HwModule.cpp | 89 +++ .../common/managerdefinitions/src/IOProfile.cpp | 12 +- .../managerdefault/AudioPolicyManager.cpp | 695 ++++----------------- .../managerdefault/AudioPolicyManager.h | 73 +-- 20 files changed, 977 insertions(+), 653 deletions(-) create mode 100755 services/audiopolicy/common/include/policy.h (limited to 'services') diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk index fb56fd8..334967e 100644 --- a/services/audiopolicy/Android.mk +++ b/services/audiopolicy/Android.mk @@ -16,13 +16,13 @@ else LOCAL_SRC_FILES += \ service/AudioPolicyInterfaceImpl.cpp \ service/AudioPolicyClientImpl.cpp - endif LOCAL_C_INCLUDES := \ $(TOPDIR)frameworks/av/services/audioflinger \ $(call include-path-for, audio-effects) \ - $(call include-path-for, audio-utils) + $(call include-path-for, audio-utils) \ + $(TOPDIR)frameworks/av/services/audiopolicy/common/include LOCAL_SHARED_LIBRARIES := \ libcutils \ @@ -63,6 +63,9 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libsoundtrigger +LOCAL_C_INCLUDES += \ + $(TOPDIR)frameworks/av/services/audiopolicy/common/include \ + LOCAL_STATIC_LIBRARIES := \ libmedia_helper \ libaudiopolicycomponents @@ -84,6 +87,9 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libaudiopolicycomponents +LOCAL_C_INCLUDES += \ + $(TOPDIR)frameworks/av/services/audiopolicy/common/include \ + LOCAL_MODULE:= libaudiopolicymanager include $(BUILD_SHARED_LIBRARY) diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h new file mode 100755 index 0000000..a2327ee --- /dev/null +++ b/services/audiopolicy/common/include/policy.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +// For mixed output and inputs, the policy will use max mixer sampling rates. +// Do not limit sampling rate otherwise +#define MAX_MIXER_SAMPLING_RATE 48000 + +// For mixed output and inputs, the policy will use max mixer channel count. +// Do not limit channel count otherwise +#define MAX_MIXER_CHANNEL_COUNT 8 + +/** + * A device mask for all audio input devices that are considered "virtual" when evaluating + * active inputs in getActiveInput() + */ +#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_FM_TUNER) + + +/** + * A device mask for all audio input and output devices where matching inputs/outputs on device + * type alone is not enough: the address must match too + */ +#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \ + AUDIO_DEVICE_OUT_REMOTE_SUBMIX) + +/** + * Check if the state given correspond to an in call state. + * @TODO find a better name for widely call state + * + * @param[in] state to consider + * + * @return true if given state represents a device in a telephony or VoIP call + */ +static inline bool is_state_in_call(int state) +{ + return (state == AUDIO_MODE_IN_CALL) || (state == AUDIO_MODE_IN_COMMUNICATION); +} + +/** + * Check if the input device given is considered as a virtual device. + * + * @param[in] device to consider + * + * @return true if the device is a virtual one, false otherwise. + */ +static bool is_virtual_input_device(audio_devices_t device) +{ + if ((device & AUDIO_DEVICE_BIT_IN) != 0) { + device &= ~AUDIO_DEVICE_BIT_IN; + if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) + return true; + } + return false; +} + +/** + * Check whether the device type is one + * where addresses are used to distinguish between one connected device and another + * + * @param[in] device to consider + * + * @return true if the device needs distinguish on address, false otherwise.. + */ +static bool device_distinguishes_on_address(audio_devices_t device) +{ + return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL & ~AUDIO_DEVICE_BIT_IN) != 0); +} diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk index d9d1477..bc6900b 100644 --- a/services/audiopolicy/common/managerdefinitions/Android.mk +++ b/services/audiopolicy/common/managerdefinitions/Android.mk @@ -20,6 +20,7 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_C_INCLUDES += \ $(LOCAL_PATH)/include \ + $(TOPDIR)frameworks/av/services/audiopolicy/common/include \ LOCAL_EXPORT_C_INCLUDE_DIRS := \ $(LOCAL_PATH)/include diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h index 599c295..7536a37 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h @@ -20,6 +20,7 @@ #include #include #include +#include namespace android { @@ -34,6 +35,8 @@ public: AudioInputDescriptor(const sp& profile); void setIoHandle(audio_io_handle_t ioHandle); + audio_module_handle_t getModuleHandle() const; + status_t dump(int fd); audio_port_handle_t mId; @@ -56,4 +59,27 @@ public: void toAudioPort(struct audio_port *port) const; }; +class AudioInputCollection : + public DefaultKeyedVector< audio_io_handle_t, sp > +{ +public: + bool isSourceActive(audio_source_t source) const; + + sp getInputFromId(audio_port_handle_t id) const; + + uint32_t activeInputsCount() const; + + /** + * return io handle of active input or 0 if no input is active + * Only considers inputs from physical devices (e.g. main mic, headset mic) when + * ignoreVirtualInputs is true. + */ + audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true); + + audio_devices_t getSupportedDevices(audio_io_handle_t handle) const; + + status_t dump(int fd) const; +}; + + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h index 8469b81..e2f1bbf 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h @@ -20,6 +20,7 @@ #include "ApmImplDefinitions.h" #include #include +#include #include namespace android { @@ -54,6 +55,8 @@ public: virtual sp getAudioPort() const { return mProfile; } void toAudioPort(struct audio_port *port) const; + audio_module_handle_t getModuleHandle() const; + audio_port_handle_t mId; audio_io_handle_t mIoHandle; // output handle uint32_t mLatency; // @@ -73,4 +76,38 @@ public: uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only) }; +class AudioOutputCollection : + public DefaultKeyedVector< audio_io_handle_t, sp > +{ +public: + bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const; + + /** + * return whether a stream is playing remotely, override to change the definition of + * local/remote playback, used for instance by notification manager to not make + * media players lose audio focus when not playing locally + * For the base implementation, "remotely" means playing during screen mirroring which + * uses an output for playback with a non-empty, non "0" address. + */ + bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const; + + /** + * returns the A2DP output handle if it is open or 0 otherwise + */ + audio_io_handle_t getA2dpOutput() const; + + sp getOutputFromId(audio_port_handle_t id) const; + + sp getPrimaryOutput() const; + + /** + * return true if any output is playing anything besides the stream to ignore + */ + bool isAnyOutputActive(audio_stream_type_t streamToIgnore) const; + + audio_devices_t getSupportedDevices(audio_io_handle_t handle) const; + + status_t dump(int fd) const; +}; + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h index 6e8fb32..385f257 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioPatch.h @@ -17,8 +17,10 @@ #pragma once #include +#include #include #include +#include namespace android { @@ -38,4 +40,16 @@ private: static volatile int32_t mNextUniqueId; }; +class AudioPatchCollection : public DefaultKeyedVector > +{ +public: + status_t addAudioPatch(audio_patch_handle_t handle, const sp& patch); + + status_t removeAudioPatch(audio_patch_handle_t handle); + + status_t listAudioPatches(unsigned int *num_patches, struct audio_patch *patches) const; + + status_t dump(int fd) const; +}; + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h index 52e845c..4f7f2bc 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h @@ -23,19 +23,16 @@ #include #include -#define MAX_MIXER_SAMPLING_RATE 48000 -#define MAX_MIXER_CHANNEL_COUNT 8 - namespace android { class HwModule; class AudioGain; -class AudioPort: public virtual RefBase +class AudioPort : public virtual RefBase { public: AudioPort(const String8& name, audio_port_type_t type, - audio_port_role_t role, const sp& module); + audio_port_role_t role, const sp& module); virtual ~AudioPort() {} audio_port_handle_t getHandle() { return mId; } @@ -78,6 +75,8 @@ public: static const audio_format_t sPcmFormatCompareTable[]; static int compareFormats(audio_format_t format1, audio_format_t format2); + audio_module_handle_t getModuleHandle() const; + void dump(int fd, int spaces) const; String8 mName; @@ -106,7 +105,7 @@ private: static volatile int32_t mNextUniqueId; }; -class AudioPortConfig: public virtual RefBase +class AudioPortConfig : public virtual RefBase { public: AudioPortConfig(); diff --git a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h index 45e96d9..53cb4a3 100644 --- a/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h +++ b/services/audiopolicy/common/managerdefinitions/include/ConfigParsingUtils.h @@ -16,8 +16,16 @@ #pragma once +#include "DeviceDescriptor.h" +#include "HwModule.h" +#include "audio_policy_conf.h" #include -#include +#include +#include +#include +#include +#include +#include namespace android { @@ -161,6 +169,32 @@ public: static uint32_t parseOutputFlagNames(char *name); static uint32_t parseInputFlagNames(char *name); static audio_devices_t parseDeviceNames(char *name); + + static void loadHwModules(cnode *root, HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled); + + static void loadGlobalConfig(cnode *root, const sp& module, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled); + + static status_t loadAudioPolicyConfig(const char *path, + HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled); + +private: + static void loadHwModule(cnode *root, HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled); }; }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h index e63ea2b..b9e1d4a 100644 --- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h @@ -22,10 +22,11 @@ #include #include #include +#include namespace android { -class DeviceDescriptor: public AudioPort, public AudioPortConfig +class DeviceDescriptor : public AudioPort, public AudioPortConfig { public: DeviceDescriptor(const String8& name, audio_devices_t type); @@ -43,12 +44,16 @@ public: virtual void loadGains(cnode *root); virtual void toAudioPort(struct audio_port *port) const; + audio_devices_t type() const { return mDeviceType; } status_t dump(int fd, int spaces, int index) const; - audio_devices_t mDeviceType; String8 mAddress; + audio_port_handle_t mId; static String8 emptyNameStr; + +private: + audio_devices_t mDeviceType; }; class DeviceVector : public SortedVector< sp > @@ -56,9 +61,9 @@ class DeviceVector : public SortedVector< sp > public: DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {} - ssize_t add(const sp& item); - ssize_t remove(const sp& item); - ssize_t indexOf(const sp& item) const; + ssize_t add(const sp& item); + ssize_t remove(const sp& item); + ssize_t indexOf(const sp& item) const; audio_devices_t types() const { return mDeviceTypes; } @@ -69,8 +74,13 @@ public: DeviceVector getDevicesFromType(audio_devices_t types) const; sp getDeviceFromId(audio_port_handle_t id) const; sp getDeviceFromName(const String8& name) const; - DeviceVector getDevicesFromTypeAddr(audio_devices_t type, String8 address) - const; + DeviceVector getDevicesFromTypeAddr(audio_devices_t type, String8 address) const; + + audio_devices_t getDevicesFromHwModule(audio_module_handle_t moduleHandle) const; + + audio_policy_dev_state_t getDeviceConnectionState(const sp &devDesc) const; + + status_t dump(int fd, const String8 &direction) const; private: void refreshTypes(); diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h index 3d4e2ad..92c3ea2 100644 --- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h +++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h @@ -45,6 +45,8 @@ public: audio_devices_t device, String8 address); status_t removeInputProfile(String8 name); + audio_module_handle_t getHandle() const { return mHandle; } + void dump(int fd); const char *const mName; // base name of the audio HW module (primary, a2dp ...) @@ -55,4 +57,18 @@ public: DeviceVector mDeclaredDevices; // devices declared in audio_policy.conf }; +class HwModuleCollection : public Vector< sp > +{ +public: + sp getModuleFromName(const char *name) const; + + sp getModuleForDevice(audio_devices_t device) const; + + sp getDeviceDescriptor(const audio_devices_t device, + const char *device_address, + const char *device_name) const; + + status_t dump(int fd) const; +}; + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp index fa7761a..fa66728 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp @@ -22,6 +22,7 @@ #include "AudioGain.h" #include "HwModule.h" #include +#include namespace android { @@ -46,9 +47,13 @@ void AudioInputDescriptor::setIoHandle(audio_io_handle_t ioHandle) mIoHandle = ioHandle; } -void AudioInputDescriptor::toAudioPortConfig( - struct audio_port_config *dstConfig, - const struct audio_port_config *srcConfig) const +audio_module_handle_t AudioInputDescriptor::getModuleHandle() const +{ + return mProfile->getModuleHandle(); +} + +void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig, + const struct audio_port_config *srcConfig) const { ALOG_ASSERT(mProfile != 0, "toAudioPortConfig() called on input with null profile %d", mIoHandle); @@ -68,8 +73,7 @@ void AudioInputDescriptor::toAudioPortConfig( dstConfig->ext.mix.usecase.source = mInputSource; } -void AudioInputDescriptor::toAudioPort( - struct audio_port *port) const +void AudioInputDescriptor::toAudioPort(struct audio_port *port) const { ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle); @@ -107,4 +111,77 @@ status_t AudioInputDescriptor::dump(int fd) return NO_ERROR; } +bool AudioInputCollection::isSourceActive(audio_source_t source) const +{ + for (size_t i = 0; i < size(); i++) { + const sp inputDescriptor = valueAt(i); + if (inputDescriptor->mRefCount == 0) { + continue; + } + if (inputDescriptor->mInputSource == (int)source) { + return true; + } + } + return false; +} + +sp AudioInputCollection::getInputFromId(audio_port_handle_t id) const +{ + sp inputDesc = NULL; + for (size_t i = 0; i < size(); i++) { + inputDesc = valueAt(i); + if (inputDesc->mId == id) { + break; + } + } + return inputDesc; +} + +uint32_t AudioInputCollection::activeInputsCount() const +{ + uint32_t count = 0; + for (size_t i = 0; i < size(); i++) { + const sp desc = valueAt(i); + if (desc->mRefCount > 0) { + count++; + } + } + return count; +} + +audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs) +{ + for (size_t i = 0; i < size(); i++) { + const sp input_descriptor = valueAt(i); + if ((input_descriptor->mRefCount > 0) + && (!ignoreVirtualInputs || !is_virtual_input_device(input_descriptor->mDevice))) { + return keyAt(i); + } + } + return 0; +} + +audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const +{ + sp inputDesc = valueFor(handle); + audio_devices_t devices = inputDesc->mProfile->mSupportedDevices.types(); + return devices; +} + +status_t AudioInputCollection::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + + snprintf(buffer, SIZE, "\nInputs dump:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < size(); i++) { + snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i)); + write(fd, buffer, strlen(buffer)); + valueAt(i)->dump(fd); + } + + return NO_ERROR; +} + }; //namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 4c5509d..cdb5b51 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -23,10 +23,13 @@ #include "HwModule.h" #include +// A device mask for all audio output devices that are considered "remote" when evaluating +// active output devices in isStreamActiveRemotely() +#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX + namespace android { -AudioOutputDescriptor::AudioOutputDescriptor( - const sp& profile) +AudioOutputDescriptor::AudioOutputDescriptor(const sp& profile) : mId(0), mIoHandle(0), mLatency(0), mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL), mPatchHandle(0), @@ -53,6 +56,11 @@ AudioOutputDescriptor::AudioOutputDescriptor( } } +audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const +{ + return mProfile->getModuleHandle(); +} + audio_devices_t AudioOutputDescriptor::device() const { if (isDuplicated()) { @@ -134,8 +142,8 @@ bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const } bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, - uint32_t inPastMs, - nsecs_t sysTime) const + uint32_t inPastMs, + nsecs_t sysTime) const { if (mRefCount[stream] != 0) { return true; @@ -218,6 +226,108 @@ status_t AudioOutputDescriptor::dump(int fd) return NO_ERROR; } +bool AudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const +{ + nsecs_t sysTime = systemTime(); + for (size_t i = 0; i < this->size(); i++) { + const sp outputDesc = this->valueAt(i); + if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { + return true; + } + } + return false; +} + +bool AudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, + uint32_t inPastMs) const +{ + nsecs_t sysTime = systemTime(); + for (size_t i = 0; i < size(); i++) { + const sp outputDesc = valueAt(i); + if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && + outputDesc->isStreamActive(stream, inPastMs, sysTime)) { + // do not consider re routing (when the output is going to a dynamic policy) + // as "remote playback" + if (outputDesc->mPolicyMix == NULL) { + return true; + } + } + } + return false; +} + +audio_io_handle_t AudioOutputCollection::getA2dpOutput() const +{ + for (size_t i = 0; i < size(); i++) { + sp outputDesc = valueAt(i); + if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { + return this->keyAt(i); + } + } + return 0; +} + +sp AudioOutputCollection::getPrimaryOutput() const +{ + for (size_t i = 0; i < size(); i++) { + const sp outputDesc = valueAt(i); + if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { + return outputDesc; + } + } + return NULL; +} +sp AudioOutputCollection::getOutputFromId(audio_port_handle_t id) const +{ + sp outputDesc = NULL; + for (size_t i = 0; i < size(); i++) { + outputDesc = valueAt(i); + if (outputDesc->mId == id) { + break; + } + } + return outputDesc; +} + +bool AudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const +{ + for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { + if (s == (size_t) streamToIgnore) { + continue; + } + for (size_t i = 0; i < size(); i++) { + const sp outputDesc = valueAt(i); + if (outputDesc->mRefCount[s] != 0) { + return true; + } + } + } + return false; +} + +audio_devices_t AudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const +{ + sp outputDesc = valueFor(handle); + audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); + return devices; +} + + +status_t AudioOutputCollection::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + + snprintf(buffer, SIZE, "\nOutputs dump:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < size(); i++) { + snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); + write(fd, buffer, strlen(buffer)); + valueAt(i)->dump(fd); + } + + return NO_ERROR; +} }; //namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp index 89e7f81..3a317fa 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioPatch.cpp @@ -18,6 +18,7 @@ //#define LOG_NDEBUG 0 #include "AudioPatch.h" +#include "AudioGain.h" #include "ConfigParsingUtils.h" #include #include @@ -81,4 +82,73 @@ status_t AudioPatch::dump(int fd, int spaces, int index) const return NO_ERROR; } +status_t AudioPatchCollection::addAudioPatch(audio_patch_handle_t handle, + const sp& patch) +{ + ssize_t index = indexOfKey(handle); + + if (index >= 0) { + ALOGW("addAudioPatch() patch %d already in", handle); + return ALREADY_EXISTS; + } + add(handle, patch); + ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d" + "sink handle %d", + handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks, + patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id); + return NO_ERROR; +} + +status_t AudioPatchCollection::removeAudioPatch(audio_patch_handle_t handle) +{ + ssize_t index = indexOfKey(handle); + + if (index < 0) { + ALOGW("removeAudioPatch() patch %d not in", handle); + return ALREADY_EXISTS; + } + ALOGV("removeAudioPatch() handle %d af handle %d", handle, valueAt(index)->mAfPatchHandle); + removeItemsAt(index); + return NO_ERROR; +} + +status_t AudioPatchCollection::listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches) const +{ + if (num_patches == NULL || (*num_patches != 0 && patches == NULL)) { + return BAD_VALUE; + } + ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu", + *num_patches, patches, size()); + if (patches == NULL) { + *num_patches = 0; + } + + size_t patchesWritten = 0; + size_t patchesMax = *num_patches; + for (size_t i = 0; i < size() && patchesWritten < patchesMax; i++) { + const sp patch = valueAt(i); + patches[patchesWritten] = patch->mPatch; + patches[patchesWritten++].id = patch->mHandle; + ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d", + i, patch->mPatch.num_sources, patch->mPatch.num_sinks); + } + *num_patches = size(); + + ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches); + return NO_ERROR; +} + +status_t AudioPatchCollection::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + snprintf(buffer, SIZE, "\nAudio Patches:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < size(); i++) { + valueAt(i)->dump(fd, 2, i); + } + return NO_ERROR; +} + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp index d34aac1..46a119e 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp @@ -22,6 +22,7 @@ #include "AudioGain.h" #include "ConfigParsingUtils.h" #include "audio_policy_conf.h" +#include namespace android { @@ -30,7 +31,7 @@ int32_t volatile AudioPort::mNextUniqueId = 1; // --- AudioPort class implementation AudioPort::AudioPort(const String8& name, audio_port_type_t type, - audio_port_role_t role, const sp& module) : + audio_port_role_t role, const sp& module) : mName(name), mType(type), mRole(role), mModule(module), mFlags(0), mId(0) { mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || @@ -48,6 +49,11 @@ audio_port_handle_t AudioPort::getNextUniqueId() return static_cast(android_atomic_inc(&mNextUniqueId)); } +audio_module_handle_t AudioPort::getModuleHandle() const +{ + return mModule->mHandle; +} + void AudioPort::toAudioPort(struct audio_port *port) const { port->role = mRole; diff --git a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp index 300f35a..fe5bc5f 100644 --- a/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp @@ -18,7 +18,10 @@ //#define LOG_NDEBUG 0 #include "ConfigParsingUtils.h" +#include "AudioGain.h" +#include #include +#include namespace android { @@ -119,4 +122,167 @@ audio_devices_t ConfigParsingUtils::parseDeviceNames(char *name) return device; } +//static +void ConfigParsingUtils::loadHwModule(cnode *root, HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnable) +{ + status_t status = NAME_NOT_FOUND; + cnode *node; + sp module = new HwModule(root->name); + + node = config_find(root, DEVICES_TAG); + if (node != NULL) { + node = node->first_child; + while (node) { + ALOGV("loadHwModule() loading device %s", node->name); + status_t tmpStatus = module->loadDevice(node); + if (status == NAME_NOT_FOUND || status == NO_ERROR) { + status = tmpStatus; + } + node = node->next; + } + } + node = config_find(root, OUTPUTS_TAG); + if (node != NULL) { + node = node->first_child; + while (node) { + ALOGV("loadHwModule() loading output %s", node->name); + status_t tmpStatus = module->loadOutput(node); + if (status == NAME_NOT_FOUND || status == NO_ERROR) { + status = tmpStatus; + } + node = node->next; + } + } + node = config_find(root, INPUTS_TAG); + if (node != NULL) { + node = node->first_child; + while (node) { + ALOGV("loadHwModule() loading input %s", node->name); + status_t tmpStatus = module->loadInput(node); + if (status == NAME_NOT_FOUND || status == NO_ERROR) { + status = tmpStatus; + } + node = node->next; + } + } + loadGlobalConfig(root, module, availableInputDevices, availableOutputDevices, + defaultOutputDevices, isSpeakerDrcEnable); + + if (status == NO_ERROR) { + hwModules.add(module); + } +} + +//static +void ConfigParsingUtils::loadHwModules(cnode *root, HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled) +{ + cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); + if (node == NULL) { + return; + } + + node = node->first_child; + while (node) { + ALOGV("loadHwModules() loading module %s", node->name); + loadHwModule(node, hwModules, availableInputDevices, availableOutputDevices, + defaultOutputDevices, isSpeakerDrcEnabled); + node = node->next; + } +} + +//static +void ConfigParsingUtils::loadGlobalConfig(cnode *root, const sp& module, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevice, + bool &speakerDrcEnabled) +{ + cnode *node = config_find(root, GLOBAL_CONFIG_TAG); + + if (node == NULL) { + return; + } + DeviceVector declaredDevices; + if (module != NULL) { + declaredDevices = module->mDeclaredDevices; + } + + node = node->first_child; + while (node) { + if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { + availableOutputDevices.loadDevicesFromName((char *)node->value, + declaredDevices); + ALOGV("loadGlobalConfig() Attached Output Devices %08x", + availableOutputDevices.types()); + } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { + audio_devices_t device = (audio_devices_t)stringToEnum( + sDeviceNameToEnumTable, + ARRAY_SIZE(sDeviceNameToEnumTable), + (char *)node->value); + if (device != AUDIO_DEVICE_NONE) { + defaultOutputDevice = new DeviceDescriptor(String8("default-output"), device); + } else { + ALOGW("loadGlobalConfig() default device not specified"); + } + ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", defaultOutputDevice->type()); + } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { + availableInputDevices.loadDevicesFromName((char *)node->value, + declaredDevices); + ALOGV("loadGlobalConfig() Available InputDevices %08x", availableInputDevices.types()); + } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { + speakerDrcEnabled = stringToBool((char *)node->value); + ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", speakerDrcEnabled); + } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { + uint32_t major, minor; + sscanf((char *)node->value, "%u.%u", &major, &minor); + module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); + ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", + module->mHalVersion, major, minor); + } + node = node->next; + } +} + +//static +status_t ConfigParsingUtils::loadAudioPolicyConfig(const char *path, + HwModuleCollection &hwModules, + DeviceVector &availableInputDevices, + DeviceVector &availableOutputDevices, + sp &defaultOutputDevices, + bool &isSpeakerDrcEnabled) +{ + cnode *root; + char *data; + + data = (char *)load_file(path, NULL); + if (data == NULL) { + return -ENODEV; + } + root = config_node("", ""); + config_load(root, data); + + loadHwModules(root, hwModules, + availableInputDevices, availableOutputDevices, + defaultOutputDevices, isSpeakerDrcEnabled); + // legacy audio_policy.conf files have one global_configuration section + loadGlobalConfig(root, hwModules.getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY), + availableInputDevices, availableOutputDevices, + defaultOutputDevices, isSpeakerDrcEnabled); + config_free(root); + free(root); + free(data); + + ALOGI("loadAudioPolicyConfig() loaded %s\n", path); + + return NO_ERROR; +} + }; // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp index 7f098ab..7df7d75 100644 --- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp @@ -27,11 +27,11 @@ namespace android { String8 DeviceDescriptor::emptyNameStr = String8(""); DeviceDescriptor::DeviceDescriptor(const String8& name, audio_devices_t type) : - AudioPort(name, AUDIO_PORT_TYPE_DEVICE, - audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : - AUDIO_PORT_ROLE_SOURCE, - NULL), - mDeviceType(type), mAddress("") + AudioPort(name, AUDIO_PORT_TYPE_DEVICE, + audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : + AUDIO_PORT_ROLE_SOURCE, + NULL), + mAddress(""), mDeviceType(type) { } @@ -60,7 +60,7 @@ void DeviceVector::refreshTypes() { mDeviceTypes = AUDIO_DEVICE_NONE; for(size_t i = 0; i < size(); i++) { - mDeviceTypes |= itemAt(i)->mDeviceType; + mDeviceTypes |= itemAt(i)->type(); } ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes); } @@ -85,7 +85,7 @@ ssize_t DeviceVector::add(const sp& item) refreshTypes(); } } else { - ALOGW("DeviceVector::add device %08x already in", item->mDeviceType); + ALOGW("DeviceVector::add device %08x already in", item->type()); ret = -1; } return ret; @@ -97,7 +97,7 @@ ssize_t DeviceVector::remove(const sp& item) ssize_t ret = indexOf(item); if (ret < 0) { - ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType); + ALOGW("DeviceVector::remove device %08x not in", item->type()); } else { ret = SortedVector::removeAt(ret); if (ret >= 0) { @@ -107,6 +107,17 @@ ssize_t DeviceVector::remove(const sp& item) return ret; } +audio_devices_t DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const +{ + audio_devices_t devices = AUDIO_DEVICE_NONE; + for (size_t i = 0; i < size(); i++) { + if (itemAt(i)->getModuleHandle() == moduleHandle) { + devices |= itemAt(i)->type(); + } + } + return devices; +} + void DeviceVector::loadDevicesFromType(audio_devices_t types) { DeviceVector deviceList; @@ -154,7 +165,7 @@ sp DeviceVector::getDevice(audio_devices_t type, String8 addre { sp device; for (size_t i = 0; i < size(); i++) { - if (itemAt(i)->mDeviceType == type) { + if (itemAt(i)->type() == type) { if (address == "" || itemAt(i)->mAddress == address) { device = itemAt(i); if (itemAt(i)->mAddress == address) { @@ -192,7 +203,7 @@ DeviceVector DeviceVector::getDevicesFromType(audio_devices_t type) const devices.add(itemAt(i)); type &= ~curType; ALOGV("DeviceVector::getDevicesFromType() for type %x found %p", - itemAt(i)->mDeviceType, itemAt(i).get()); + itemAt(i)->type(), itemAt(i).get()); } } return devices; @@ -203,7 +214,7 @@ DeviceVector DeviceVector::getDevicesFromTypeAddr( { DeviceVector devices; for (size_t i = 0; i < size(); i++) { - if (itemAt(i)->mDeviceType == type) { + if (itemAt(i)->type() == type) { if (itemAt(i)->mAddress == address) { devices.add(itemAt(i)); } @@ -224,6 +235,26 @@ sp DeviceVector::getDeviceFromName(const String8& name) const return device; } + +status_t DeviceVector::dump(int fd, const String8 &direction) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + + snprintf(buffer, SIZE, "\n Available %s devices:\n", direction.string()); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < size(); i++) { + itemAt(i)->dump(fd, 2, i); + } + return NO_ERROR; +} + +audio_policy_dev_state_t DeviceVector::getDeviceConnectionState(const sp &devDesc) const +{ + ssize_t index = indexOf(devDesc); + return index >= 0 ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; +} + void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig) const { diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp index a0ea185..8004303 100644 --- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp @@ -23,6 +23,7 @@ #include "ConfigParsingUtils.h" #include "audio_policy_conf.h" #include +#include namespace android { @@ -279,4 +280,92 @@ void HwModule::dump(int fd) } } +sp HwModuleCollection::getModuleFromName(const char *name) const +{ + sp module; + + for (size_t i = 0; i < size(); i++) + { + if (strcmp(itemAt(i)->mName, name) == 0) { + return itemAt(i); + } + } + return module; +} + + +sp HwModuleCollection::getModuleForDevice(audio_devices_t device) const +{ + sp module; + + for (size_t i = 0; i < size(); i++) { + if (itemAt(i)->mHandle == 0) { + continue; + } + if (audio_is_output_device(device)) { + for (size_t j = 0; j < itemAt(i)->mOutputProfiles.size(); j++) + { + if (itemAt(i)->mOutputProfiles[j]->mSupportedDevices.types() & device) { + return itemAt(i); + } + } + } else { + for (size_t j = 0; j < itemAt(i)->mInputProfiles.size(); j++) { + if (itemAt(i)->mInputProfiles[j]->mSupportedDevices.types() & + device & ~AUDIO_DEVICE_BIT_IN) { + return itemAt(i); + } + } + } + } + return module; +} + +sp HwModuleCollection::getDeviceDescriptor(const audio_devices_t device, + const char *device_address, + const char *device_name) const +{ + String8 address = (device_address == NULL) ? String8("") : String8(device_address); + // handle legacy remote submix case where the address was not always specified + if (device_distinguishes_on_address(device) && (address.length() == 0)) { + address = String8("0"); + } + + for (size_t i = 0; i < size(); i++) { + const sp hwModule = itemAt(i); + if (hwModule->mHandle == 0) { + continue; + } + DeviceVector deviceList = + hwModule->mDeclaredDevices.getDevicesFromTypeAddr(device, address); + if (!deviceList.isEmpty()) { + return deviceList.itemAt(0); + } + deviceList = hwModule->mDeclaredDevices.getDevicesFromType(device); + if (!deviceList.isEmpty()) { + return deviceList.itemAt(0); + } + } + + sp devDesc = + new DeviceDescriptor(String8(device_name != NULL ? device_name : ""), device); + devDesc->mAddress = address; + return devDesc; +} + +status_t HwModuleCollection::dump(int fd) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + + snprintf(buffer, SIZE, "\nHW Modules dump:\n"); + write(fd, buffer, strlen(buffer)); + for (size_t i = 0; i < size(); i++) { + snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); + write(fd, buffer, strlen(buffer)); + itemAt(i)->dump(fd); + } + return NO_ERROR; +} + } //namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp index 0214a2b..376dd22 100644 --- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp @@ -37,12 +37,12 @@ IOProfile::~IOProfile() // Sampling rate, format and channel mask must be specified in order to // get a valid a match bool IOProfile::isCompatibleProfile(audio_devices_t device, - String8 address, - uint32_t samplingRate, - uint32_t *updatedSamplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - uint32_t flags) const + String8 address, + uint32_t samplingRate, + uint32_t *updatedSamplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + uint32_t flags) const { const bool isPlaybackThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SOURCE; const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index a110ada..033ae49 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -24,17 +24,6 @@ #define ALOGVV(a...) do { } while(0) #endif -// A device mask for all audio input devices that are considered "virtual" when evaluating -// active inputs in getActiveInput() -#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX|AUDIO_DEVICE_IN_FM_TUNER) -// A device mask for all audio output devices that are considered "remote" when evaluating -// active output devices in isStreamActiveRemotely() -#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX -// A device mask for all audio input and output devices where matching inputs/outputs on device -// type alone is not enough: the address must match too -#define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \ - AUDIO_DEVICE_OUT_REMOTE_SUBMIX) - #include #include @@ -47,6 +36,8 @@ #include #include "AudioPolicyManager.h" #include "audio_policy_conf.h" +#include +#include namespace android { @@ -73,7 +64,8 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, // connect/disconnect only 1 device at a time if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE; - sp devDesc = getDeviceDescriptor(device, device_address, device_name); + sp devDesc = + mHwModules.getDeviceDescriptor(device, device_address, device_name); // handle output devices if (audio_is_output_device(device)) { @@ -97,7 +89,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, // register new device as available index = mAvailableOutputDevices.add(devDesc); if (index >= 0) { - sp module = getModuleForDevice(device); + sp module = mHwModules.getModuleForDevice(device); if (module == 0) { ALOGD("setDeviceConnectionState() could not find HW module for device %08x", device); @@ -184,7 +176,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, // also force a device 0 for the two outputs it is duplicated to which may override // a valid device selection on those outputs. bool force = !mOutputs.valueAt(i)->isDuplicated() - && (!deviceDistinguishesOnAddress(device) + && (!device_distinguishes_on_address(device) // always force when disconnecting (a non-duplicated device) || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE)); setOutputDevice(output, newDevice, force, 0); @@ -208,7 +200,7 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, ALOGW("setDeviceConnectionState() device already connected: %d", device); return INVALID_OPERATION; } - sp module = getModuleForDevice(device); + sp module = mHwModules.getModuleForDevice(device); if (module == NULL) { ALOGW("setDeviceConnectionState(): could not find HW module for device %08x", device); @@ -272,9 +264,10 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t device, } audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device, - const char *device_address) + const char *device_address) { - sp devDesc = getDeviceDescriptor(device, device_address, ""); + sp devDesc = mHwModules.getDeviceDescriptor(device, device_address, ""); + DeviceVector *deviceVector; if (audio_is_output_device(device)) { @@ -285,44 +278,7 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi ALOGW("getDeviceConnectionState() invalid device type %08x", device); return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; } - - ssize_t index = deviceVector->indexOf(devDesc); - if (index >= 0) { - return AUDIO_POLICY_DEVICE_STATE_AVAILABLE; - } else { - return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; - } -} - -sp AudioPolicyManager::getDeviceDescriptor(const audio_devices_t device, - const char *device_address, - const char *device_name) -{ - String8 address = (device_address == NULL) ? String8("") : String8(device_address); - // handle legacy remote submix case where the address was not always specified - if (deviceDistinguishesOnAddress(device) && (address.length() == 0)) { - address = String8("0"); - } - - for (size_t i = 0; i < mHwModules.size(); i++) { - if (mHwModules[i]->mHandle == 0) { - continue; - } - DeviceVector deviceList = - mHwModules[i]->mDeclaredDevices.getDevicesFromTypeAddr(device, address); - if (!deviceList.isEmpty()) { - return deviceList.itemAt(0); - } - deviceList = mHwModules[i]->mDeclaredDevices.getDevicesFromType(device); - if (!deviceList.isEmpty()) { - return deviceList.itemAt(0); - } - } - - sp devDesc = - new DeviceDescriptor(String8(device_name != NULL ? device_name : ""), device); - devDesc->mAddress = address; - return devDesc; + return deviceVector->getDeviceConnectionState(devDesc); } void AudioPolicyManager::updateCallRouting(audio_devices_t rxDevice, int delayMs) @@ -664,7 +620,7 @@ void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage, } } - audio_io_handle_t activeInput = getActiveInput(); + audio_io_handle_t activeInput = mInputs.getActiveInput(); if (activeInput != 0) { setInputDevice(activeInput, getNewInputDevice(activeInput)); } @@ -709,11 +665,11 @@ sp AudioPolicyManager::getProfileForDirectOutput( } audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo) { routing_strategy strategy = getStrategy(stream); audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); @@ -797,7 +753,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr, } ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x", - attributes.usage, attributes.content_type, attributes.tags, attributes.flags); + attributes.usage, attributes.content_type, attributes.tags, attributes.flags); routing_strategy strategy = (routing_strategy) getStrategyForAttr(&attributes); audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/); @@ -1093,7 +1049,7 @@ status_t AudioPolicyManager::startOutput(audio_io_handle_t output, uint32_t beaconMuteLatency = 0; if (stream == AUDIO_STREAM_TTS) { ALOGV("\t found BEACON stream"); - if (isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { + if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) { return INVALID_OPERATION; } else { beaconMuteLatency = handleEventForBeacon(STARTING_BEACON); @@ -1272,7 +1228,7 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output, sp outputDesc = mOutputs.valueAt(index); if (outputDesc->isActive()) { mpClientInterface->closeOutput(output); - mOutputs.removeItem(output); + removeOutput(output); mTestOutputs[testIndex] = 0; } return; @@ -1480,10 +1436,10 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } // virtual input devices are compatible with other input devices - if (!isVirtualInputDevice(inputDesc->mDevice)) { + if (!is_virtual_input_device(inputDesc->mDevice)) { // for a non-virtual input device, check if there is another (non-virtual) active input - audio_io_handle_t activeInput = getActiveInput(); + audio_io_handle_t activeInput = mInputs.getActiveInput(); if (activeInput != 0 && activeInput != input) { // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed, @@ -1501,7 +1457,7 @@ status_t AudioPolicyManager::startInput(audio_io_handle_t input, } if (inputDesc->mRefCount == 0) { - if (activeInputsCount() == 0) { + if (mInputs.activeInputsCount() == 0) { SoundTrigger::setCaptureState(true); } setInputDevice(input, getNewInputDevice(input), true /* force */); @@ -1573,7 +1529,7 @@ status_t AudioPolicyManager::stopInput(audio_io_handle_t input, resetInputDevice(input); - if (activeInputsCount() == 0) { + if (mInputs.activeInputsCount() == 0) { SoundTrigger::setCaptureState(false); } } @@ -1654,8 +1610,8 @@ void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream, } status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream, - int index, - audio_devices_t device) + int index, + audio_devices_t device) { if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) { @@ -1906,36 +1862,6 @@ bool AudioPolicyManager::isNonOffloadableEffectEnabled() return false; } -bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const -{ - nsecs_t sysTime = systemTime(); - for (size_t i = 0; i < mOutputs.size(); i++) { - const sp outputDesc = mOutputs.valueAt(i); - if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { - return true; - } - } - return false; -} - -bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream, - uint32_t inPastMs) const -{ - nsecs_t sysTime = systemTime(); - for (size_t i = 0; i < mOutputs.size(); i++) { - const sp outputDesc = mOutputs.valueAt(i); - if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && - outputDesc->isStreamActive(stream, inPastMs, sysTime)) { - // do not consider re routing (when the output is going to a dynamic policy) - // as "remote playback" - if (outputDesc->mPolicyMix == NULL) { - return true; - } - } - } - return false; -} - bool AudioPolicyManager::isSourceActive(audio_source_t source) const { for (size_t i = 0; i < mInputs.size(); i++) { @@ -2111,41 +2037,11 @@ status_t AudioPolicyManager::dump(int fd) mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO]); result.append(buffer); - snprintf(buffer, SIZE, " Available output devices:\n"); - result.append(buffer); - write(fd, result.string(), result.size()); - for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) { - mAvailableOutputDevices[i]->dump(fd, 2, i); - } - snprintf(buffer, SIZE, "\n Available input devices:\n"); - write(fd, buffer, strlen(buffer)); - for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { - mAvailableInputDevices[i]->dump(fd, 2, i); - } - - snprintf(buffer, SIZE, "\nHW Modules dump:\n"); - write(fd, buffer, strlen(buffer)); - for (size_t i = 0; i < mHwModules.size(); i++) { - snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1); - write(fd, buffer, strlen(buffer)); - mHwModules[i]->dump(fd); - } - - snprintf(buffer, SIZE, "\nOutputs dump:\n"); - write(fd, buffer, strlen(buffer)); - for (size_t i = 0; i < mOutputs.size(); i++) { - snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i)); - write(fd, buffer, strlen(buffer)); - mOutputs.valueAt(i)->dump(fd); - } - - snprintf(buffer, SIZE, "\nInputs dump:\n"); - write(fd, buffer, strlen(buffer)); - for (size_t i = 0; i < mInputs.size(); i++) { - snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i)); - write(fd, buffer, strlen(buffer)); - mInputs.valueAt(i)->dump(fd); - } + mAvailableOutputDevices.dump(fd, String8("output")); + mAvailableInputDevices.dump(fd, String8("input")); + mHwModules.dump(fd); + mOutputs.dump(fd); + mInputs.dump(fd); snprintf(buffer, SIZE, "\nStreams dump:\n"); write(fd, buffer, strlen(buffer)); @@ -2170,11 +2066,7 @@ status_t AudioPolicyManager::dump(int fd) mEffects.valueAt(i)->dump(fd); } - snprintf(buffer, SIZE, "\nAudio Patches:\n"); - write(fd, buffer, strlen(buffer)); - for (size_t i = 0; i < mAudioPatches.size(); i++) { - mAudioPatches[i]->dump(fd, 2, i); - } + mAudioPatches.dump(fd); return NO_ERROR; } @@ -2310,93 +2202,6 @@ status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused) return NO_ERROR; } -sp AudioPolicyManager::getOutputFromId( - audio_port_handle_t id) const -{ - sp outputDesc = NULL; - for (size_t i = 0; i < mOutputs.size(); i++) { - outputDesc = mOutputs.valueAt(i); - if (outputDesc->mId == id) { - break; - } - } - return outputDesc; -} - -sp AudioPolicyManager::getInputFromId( - audio_port_handle_t id) const -{ - sp inputDesc = NULL; - for (size_t i = 0; i < mInputs.size(); i++) { - inputDesc = mInputs.valueAt(i); - if (inputDesc->mId == id) { - break; - } - } - return inputDesc; -} - -sp AudioPolicyManager::getModuleForDevice( - audio_devices_t device) const -{ - sp module; - - for (size_t i = 0; i < mHwModules.size(); i++) { - if (mHwModules[i]->mHandle == 0) { - continue; - } - if (audio_is_output_device(device)) { - for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) - { - if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) { - return mHwModules[i]; - } - } - } else { - for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) { - if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() & - device & ~AUDIO_DEVICE_BIT_IN) { - return mHwModules[i]; - } - } - } - } - return module; -} - -sp AudioPolicyManager::getModuleFromName(const char *name) const -{ - sp module; - - for (size_t i = 0; i < mHwModules.size(); i++) - { - if (strcmp(mHwModules[i]->mName, name) == 0) { - return mHwModules[i]; - } - } - return module; -} - -audio_devices_t AudioPolicyManager::availablePrimaryOutputDevices() -{ - sp outputDesc = mOutputs.valueFor(mPrimaryOutput); - audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); - return devices & mAvailableOutputDevices.types(); -} - -audio_devices_t AudioPolicyManager::availablePrimaryInputDevices() -{ - audio_module_handle_t primaryHandle = - mOutputs.valueFor(mPrimaryOutput)->mProfile->mModule->mHandle; - audio_devices_t devices = AUDIO_DEVICE_NONE; - for (size_t i = 0; i < mAvailableInputDevices.size(); i++) { - if (mAvailableInputDevices[i]->mModule->mHandle == primaryHandle) { - devices |= mAvailableInputDevices[i]->mDeviceType; - } - } - return devices; -} - status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, audio_patch_handle_t *handle, uid_t uid) @@ -2452,7 +2257,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, } if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { - sp outputDesc = getOutputFromId(patch->sources[0].id); + sp outputDesc = mOutputs.getOutputFromId(patch->sources[0].id); if (outputDesc == NULL) { ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id); return BAD_VALUE; @@ -2481,15 +2286,14 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return BAD_VALUE; } - if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, + if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(), devDesc->mAddress, patch->sources[0].sample_rate, - NULL, // updatedSamplingRate - patch->sources[0].format, - patch->sources[0].channel_mask, - AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) { - ALOGV("createAudioPatch() profile not supported for device %08x", - devDesc->mDeviceType); + NULL, // updatedSamplingRate + patch->sources[0].format, + patch->sources[0].channel_mask, + AUDIO_OUTPUT_FLAG_NONE /*FIXME*/)) { + ALOGV("createAudioPatch() profile not supported for device %08x", devDesc->type()); return INVALID_OPERATION; } devices.add(devDesc); @@ -2521,7 +2325,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, if (patch->num_sinks > 1) { return INVALID_OPERATION; } - sp inputDesc = getInputFromId(patch->sinks[0].id); + sp inputDesc = mInputs.getInputFromId(patch->sinks[0].id); if (inputDesc == NULL) { return BAD_VALUE; } @@ -2536,7 +2340,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return BAD_VALUE; } - if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mDeviceType, + if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(), devDesc->mAddress, patch->sinks[0].sample_rate, NULL, /*updatedSampleRate*/ @@ -2550,8 +2354,8 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, } // TODO: reconfigure output format and channels here ALOGV("createAudioPatch() setting device %08x on output %d", - devDesc->mDeviceType, inputDesc->mIoHandle); - setInputDevice(inputDesc->mIoHandle, devDesc->mDeviceType, true, handle); + devDesc->type(), inputDesc->mIoHandle); + setInputDevice(inputDesc->mIoHandle, devDesc->type(), true, handle); index = mAudioPatches.indexOfKey(*handle); if (index >= 0) { if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) { @@ -2601,8 +2405,7 @@ status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch, return INVALID_OPERATION; } SortedVector outputs = - getOutputsForDevice(sinkDeviceDesc->mDeviceType, - mOutputs); + getOutputsForDevice(sinkDeviceDesc->type(), mOutputs); // if the sink device is reachable via an opened output stream, request to go via // this output stream by adding a second source to the patch description audio_io_handle_t output = selectOutput(outputs, @@ -2675,7 +2478,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, struct audio_patch *patch = &patchDesc->mPatch; patchDesc->mUid = mUidCached; if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) { - sp outputDesc = getOutputFromId(patch->sources[0].id); + sp outputDesc = mOutputs.getOutputFromId(patch->sources[0].id); if (outputDesc == NULL) { ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id); return BAD_VALUE; @@ -2688,7 +2491,7 @@ status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle, NULL); } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) { if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) { - sp inputDesc = getInputFromId(patch->sinks[0].id); + sp inputDesc = mInputs.getInputFromId(patch->sinks[0].id); if (inputDesc == NULL) { ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id); return BAD_VALUE; @@ -2718,30 +2521,11 @@ status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches, struct audio_patch *patches, unsigned int *generation) { - if (num_patches == NULL || (*num_patches != 0 && patches == NULL) || - generation == NULL) { + if (generation == NULL) { return BAD_VALUE; } - ALOGV("listAudioPatches() num_patches %d patches %p available patches %zu", - *num_patches, patches, mAudioPatches.size()); - if (patches == NULL) { - *num_patches = 0; - } - - size_t patchesWritten = 0; - size_t patchesMax = *num_patches; - for (size_t i = 0; - i < mAudioPatches.size() && patchesWritten < patchesMax; i++) { - patches[patchesWritten] = mAudioPatches[i]->mPatch; - patches[patchesWritten++].id = mAudioPatches[i]->mHandle; - ALOGV("listAudioPatches() patch %zu num_sources %d num_sinks %d", - i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks); - } - *num_patches = mAudioPatches.size(); - *generation = curAudioPortGeneration(); - ALOGV("listAudioPatches() got %zu patches needed %d", patchesWritten, *num_patches); - return NO_ERROR; + return mAudioPatches.listAudioPatches(num_patches, patches); } status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config) @@ -2760,7 +2544,7 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config * sp audioPortConfig; if (config->type == AUDIO_PORT_TYPE_MIX) { if (config->role == AUDIO_PORT_ROLE_SOURCE) { - sp outputDesc = getOutputFromId(config->id); + sp outputDesc = mOutputs.getOutputFromId(config->id); if (outputDesc == NULL) { return BAD_VALUE; } @@ -2769,7 +2553,7 @@ status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config * outputDesc->mIoHandle); audioPortConfig = outputDesc; } else if (config->role == AUDIO_PORT_ROLE_SINK) { - sp inputDesc = getInputFromId(config->id); + sp inputDesc = mInputs.getInputFromId(config->id); if (inputDesc == NULL) { return BAD_VALUE; } @@ -2843,37 +2627,6 @@ status_t AudioPolicyManager::releaseSoundTriggerSession(audio_session_t session) return NO_ERROR; } -status_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle, - const sp& patch) -{ - ssize_t index = mAudioPatches.indexOfKey(handle); - - if (index >= 0) { - ALOGW("addAudioPatch() patch %d already in", handle); - return ALREADY_EXISTS; - } - mAudioPatches.add(handle, patch); - ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d" - "sink handle %d", - handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks, - patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id); - return NO_ERROR; -} - -status_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle) -{ - ssize_t index = mAudioPatches.indexOfKey(handle); - - if (index < 0) { - ALOGW("removeAudioPatch() patch %d not in", handle); - return ALREADY_EXISTS; - } - ALOGV("removeAudioPatch() handle %d af handle %d", handle, - mAudioPatches.valueAt(index)->mAfPatchHandle); - mAudioPatches.removeItemsAt(index); - return NO_ERROR; -} - // ---------------------------------------------------------------------------- // AudioPolicyManager // ---------------------------------------------------------------------------- @@ -2906,8 +2659,12 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa } mDefaultOutputDevice = new DeviceDescriptor(String8("Speaker"), AUDIO_DEVICE_OUT_SPEAKER); - if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) { - if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) { + if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE, + mHwModules, mAvailableInputDevices, mAvailableOutputDevices, + mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) { + if (ConfigParsingUtils::loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE, + mHwModules, mAvailableInputDevices, mAvailableOutputDevices, + mDefaultOutputDevice, mSpeakerDrcEnabled) != NO_ERROR) { ALOGE("could not load audio policy configuration file, setting defaults"); defaultAudioPolicyConfig(); } @@ -2943,13 +2700,13 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa continue; } audio_devices_t profileType = outProfile->mSupportedDevices.types(); - if ((profileType & mDefaultOutputDevice->mDeviceType) != AUDIO_DEVICE_NONE) { - profileType = mDefaultOutputDevice->mDeviceType; + if ((profileType & mDefaultOutputDevice->type()) != AUDIO_DEVICE_NONE) { + profileType = mDefaultOutputDevice->type(); } else { // chose first device present in mSupportedDevices also part of // outputDeviceTypes for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { - profileType = outProfile->mSupportedDevices[k]->mDeviceType; + profileType = outProfile->mSupportedDevices[k]->type(); if ((profileType & outputDeviceTypes) != 0) { break; } @@ -2984,7 +2741,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa outputDesc->mFormat = config.format; for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) { - audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType; + audio_devices_t type = outProfile->mSupportedDevices[k]->type(); ssize_t index = mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]); // give a valid ID to an attached device once confirmed it is reachable @@ -3016,7 +2773,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa // inputDeviceTypes audio_devices_t profileType = AUDIO_DEVICE_NONE; for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { - profileType = inProfile->mSupportedDevices[k]->mDeviceType; + profileType = inProfile->mSupportedDevices[k]->type(); if (profileType & inputDeviceTypes) { break; } @@ -3052,7 +2809,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa if (status == NO_ERROR) { for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) { - audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType; + audio_devices_t type = inProfile->mSupportedDevices[k]->type(); ssize_t index = mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]); // give a valid ID to an attached device once confirmed it is reachable @@ -3071,7 +2828,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa // make sure all attached devices have been allocated a unique ID for (size_t i = 0; i < mAvailableOutputDevices.size();) { if (!mAvailableOutputDevices[i]->isAttached()) { - ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType); + ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->type()); mAvailableOutputDevices.remove(mAvailableOutputDevices[i]); continue; } @@ -3079,7 +2836,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa } for (size_t i = 0; i < mAvailableInputDevices.size();) { if (!mAvailableInputDevices[i]->isAttached()) { - ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType); + ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->type()); mAvailableInputDevices.remove(mAvailableInputDevices[i]); continue; } @@ -3087,7 +2844,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa } // make sure default device is reachable if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) { - ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType); + ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type()); } ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output"); @@ -3243,8 +3000,7 @@ bool AudioPolicyManager::threadLoop() audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle; - mOutputs.removeItem(mPrimaryOutput); - + removeOutput(mPrimaryOutput); sp outputDesc = new AudioOutputDescriptor(NULL); outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER; audio_config_t config = AUDIO_CONFIG_INITIALIZER; @@ -3308,6 +3064,11 @@ void AudioPolicyManager::addOutput(audio_io_handle_t output, sp inputDesc) { inputDesc->setIoHandle(input); @@ -3329,11 +3090,11 @@ void AudioPolicyManager::findIoHandlesByAddress(sp desc / } status_t AudioPolicyManager::checkOutputsForDevice(const sp devDesc, - audio_policy_dev_state_t state, - SortedVector& outputs, - const String8 address) + audio_policy_dev_state_t state, + SortedVector& outputs, + const String8 address) { - audio_devices_t device = devDesc->mDeviceType; + audio_devices_t device = devDesc->type(); sp desc; // erase all current sample rates, formats and channel masks devDesc->clearCapabilities(); @@ -3343,7 +3104,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de for (size_t i = 0; i < mOutputs.size(); i++) { desc = mOutputs.valueAt(i); if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) { - if (!deviceDistinguishesOnAddress(device)) { + if (!device_distinguishes_on_address(device)) { ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i)); outputs.add(mOutputs.keyAt(i)); } else { @@ -3363,7 +3124,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de { sp profile = mHwModules[i]->mOutputProfiles[j]; if (profile->mSupportedDevices.types() & device) { - if (!deviceDistinguishesOnAddress(device) || + if (!device_distinguishes_on_address(device) || address == profile->mSupportedDevices[0]->mAddress) { profiles.add(profile); ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i); @@ -3499,7 +3260,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de if (output != AUDIO_IO_HANDLE_NONE) { addOutput(output, desc); - if (deviceDistinguishesOnAddress(device) && address != "0") { + if (device_distinguishes_on_address(device) && address != "0") { ssize_t index = mPolicyMixes.indexOfKey(address); if (index >= 0) { mPolicyMixes[index]->mOutput = desc; @@ -3537,7 +3298,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de ALOGW("checkOutputsForDevice() could not open dup output for %d and %d", mPrimaryOutput, output); mpClientInterface->closeOutput(output); - mOutputs.removeItem(output); + removeOutput(output); nextAudioPortGeneration(); output = AUDIO_IO_HANDLE_NONE; } @@ -3554,7 +3315,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de outputs.add(output); devDesc->importAudioPort(profile); - if (deviceDistinguishesOnAddress(device)) { + if (device_distinguishes_on_address(device)) { ALOGV("checkOutputsForDevice(): setOutputDevice(dev=0x%x, addr=%s)", device, address.string()); setOutputDevice(output, device, true/*force*/, 0/*delay*/, @@ -3574,7 +3335,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de desc = mOutputs.valueAt(i); if (!desc->isDuplicated()) { // exact match on device - if (deviceDistinguishesOnAddress(device) && + if (device_distinguishes_on_address(device) && (desc->mProfile->mSupportedDevices.types() == device)) { findIoHandlesByAddress(desc, device, address, outputs); } else if (!(desc->mProfile->mSupportedDevices.types() @@ -3617,9 +3378,9 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp de } status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, - audio_policy_dev_state_t state, - SortedVector& inputs, - const String8 address) + audio_policy_dev_state_t state, + SortedVector& inputs, + const String8 address) { sp desc; if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) { @@ -3646,7 +3407,7 @@ status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device, sp profile = mHwModules[module_idx]->mInputProfiles[profile_index]; if (profile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) { - if (!deviceDistinguishesOnAddress(device) || + if (!device_distinguishes_on_address(device) || address == profile->mSupportedDevices[0]->mAddress) { profiles.add(profile); ALOGV("checkInputsForDevice(): adding profile %zu from module %zu", @@ -3849,7 +3610,7 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput); mpClientInterface->closeOutput(duplicatedOutput); - mOutputs.removeItem(duplicatedOutput); + removeOutput(duplicatedOutput); } } @@ -3868,7 +3629,7 @@ void AudioPolicyManager::closeOutput(audio_io_handle_t output) mpClientInterface->setParameters(output, param.toString()); mpClientInterface->closeOutput(output); - mOutputs.removeItem(output); + removeOutput(output); mPreviousOutputs = mOutputs; } @@ -3897,7 +3658,7 @@ void AudioPolicyManager::closeInput(audio_io_handle_t input) } SortedVector AudioPolicyManager::getOutputsForDevice(audio_devices_t device, - DefaultKeyedVector > openOutputs) + AudioOutputCollection openOutputs) { SortedVector outputs; @@ -3914,7 +3675,7 @@ SortedVector AudioPolicyManager::getOutputsForDevice(audio_de } bool AudioPolicyManager::vectorsEqual(SortedVector& outputs1, - SortedVector& outputs2) + SortedVector& outputs2) { if (outputs1.size() != outputs2.size()) { return false; @@ -4010,21 +3771,9 @@ void AudioPolicyManager::checkOutputForAllStrategies() checkOutputForStrategy(STRATEGY_REROUTING); } -audio_io_handle_t AudioPolicyManager::getA2dpOutput() -{ - for (size_t i = 0; i < mOutputs.size(); i++) { - sp outputDesc = mOutputs.valueAt(i); - if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { - return mOutputs.keyAt(i); - } - } - - return 0; -} - void AudioPolicyManager::checkA2dpSuspend() { - audio_io_handle_t a2dpOutput = getA2dpOutput(); + audio_io_handle_t a2dpOutput = mOutputs.getA2dpOutput(); if (a2dpOutput == 0) { mA2dpSuspended = false; return; @@ -4280,21 +4029,6 @@ void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t } } -bool AudioPolicyManager::isAnyOutputActive(audio_stream_type_t streamToIgnore) { - for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { - if (s == (size_t) streamToIgnore) { - continue; - } - for (size_t i = 0; i < mOutputs.size(); i++) { - const sp outputDesc = mOutputs.valueAt(i); - if (outputDesc->mRefCount[s] != 0) { - return true; - } - } - } - return false; -} - uint32_t AudioPolicyManager::handleEventForBeacon(int event) { switch(event) { case STARTING_OUTPUT: @@ -4349,7 +4083,7 @@ uint32_t AudioPolicyManager::setBeaconMute(bool mute) { } audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy, - bool fromCache) + bool fromCache) { uint32_t device = AUDIO_DEVICE_NONE; @@ -4442,7 +4176,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP if (!isInCall() && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0)) { + (mOutputs.getA2dpOutput() != 0)) { device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device) break; device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -4466,7 +4200,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate } device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE; if (device) break; - device = mDefaultOutputDevice->mDeviceType; + device = mDefaultOutputDevice->type(); if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); } @@ -4477,7 +4211,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate // A2DP speaker when forcing to speaker output if (!isInCall() && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0)) { + (mOutputs.getA2dpOutput() != 0)) { device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; if (device) break; } @@ -4497,7 +4231,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate if (device) break; device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER; if (device) break; - device = mDefaultOutputDevice->mDeviceType; + device = mDefaultOutputDevice->type(); if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); } @@ -4559,7 +4293,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate } if ((device2 == AUDIO_DEVICE_NONE) && (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && - (getA2dpOutput() != 0)) { + (mOutputs.getA2dpOutput() != 0)) { device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device2 == AUDIO_DEVICE_NONE) { device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; @@ -4622,7 +4356,7 @@ audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strate } if (device) break; - device = mDefaultOutputDevice->mDeviceType; + device = mDefaultOutputDevice->type(); if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); } @@ -4833,7 +4567,7 @@ uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output, // inform all input as well for (size_t i = 0; i < mInputs.size(); i++) { const sp inputDescriptor = mInputs.valueAt(i); - if (!isVirtualInputDevice(inputDescriptor->mDevice)) { + if (!is_virtual_input_device(inputDescriptor->mDevice)) { AudioParameter inputCmd = AudioParameter(); ALOGV("%s: inform input %d of device:%d", __func__, inputDescriptor->mIoHandle, device); @@ -4963,11 +4697,11 @@ status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input, } sp AudioPolicyManager::getInputProfile(audio_devices_t device, - String8 address, - uint32_t& samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_input_flags_t flags) + String8 address, + uint32_t& samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_input_flags_t flags) { // Choose an input profile based on the requested capture parameters: select the first available // profile supporting all requested parameters. @@ -4994,7 +4728,7 @@ sp AudioPolicyManager::getInputProfile(audio_devices_t device, audio_devices_t AudioPolicyManager::getDeviceAndMixForInputSource(audio_source_t inputSource, - AudioMix **policyMix) + AudioMix **policyMix) { audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; @@ -5133,45 +4867,6 @@ audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t input return device; } -bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device) -{ - if ((device & AUDIO_DEVICE_BIT_IN) != 0) { - device &= ~AUDIO_DEVICE_BIT_IN; - if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0)) - return true; - } - return false; -} - -bool AudioPolicyManager::deviceDistinguishesOnAddress(audio_devices_t device) { - return ((device & APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL & ~AUDIO_DEVICE_BIT_IN) != 0); -} - -audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs) -{ - for (size_t i = 0; i < mInputs.size(); i++) { - const sp input_descriptor = mInputs.valueAt(i); - if ((input_descriptor->mRefCount > 0) - && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) { - return mInputs.keyAt(i); - } - } - return 0; -} - -uint32_t AudioPolicyManager::activeInputsCount() const -{ - uint32_t count = 0; - for (size_t i = 0; i < mInputs.size(); i++) { - const sp desc = mInputs.valueAt(i); - if (desc->mRefCount > 0) { - count++; - } - } - return count; -} - - void AudioPolicyManager::initializeVolumeCurves() { for (int i = 0; i < AUDIO_STREAM_CNT; i++) { @@ -5199,9 +4894,9 @@ void AudioPolicyManager::initializeVolumeCurves() } float AudioPolicyManager::computeVolume(audio_stream_type_t stream, - int index, - audio_io_handle_t output, - audio_devices_t device) + int index, + audio_io_handle_t output, + audio_devices_t device) { float volume = 1.0; sp outputDesc = mOutputs.valueFor(output); @@ -5253,11 +4948,11 @@ float AudioPolicyManager::computeVolume(audio_stream_type_t stream, } status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, - int index, - audio_io_handle_t output, - audio_devices_t device, - int delayMs, - bool force) + int index, + audio_io_handle_t output, + audio_devices_t device, + int delayMs, + bool force) { // do not change actual stream volume if the stream is muted @@ -5325,9 +5020,9 @@ status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream, } void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, - audio_devices_t device, - int delayMs, - bool force) + audio_devices_t device, + int delayMs, + bool force) { ALOGVV("applyStreamVolumes() for output %d and device %x", output, device); @@ -5345,10 +5040,10 @@ void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output, } void AudioPolicyManager::setStrategyMute(routing_strategy strategy, - bool on, - audio_io_handle_t output, - int delayMs, - audio_devices_t device) + bool on, + audio_io_handle_t output, + int delayMs, + audio_devices_t device) { ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output); for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) { @@ -5362,10 +5057,10 @@ void AudioPolicyManager::setStrategyMute(routing_strategy strategy, } void AudioPolicyManager::setStreamMute(audio_stream_type_t stream, - bool on, - audio_io_handle_t output, - int delayMs, - audio_devices_t device) + bool on, + audio_io_handle_t output, + int delayMs, + audio_devices_t device) { StreamDescriptor &streamDesc = mStreams[stream]; sp outputDesc = mOutputs.valueFor(output); @@ -5491,147 +5186,6 @@ status_t AudioPolicyManager::EffectDescriptor::dump(int fd) } -// --- audio_policy.conf file parsing -// TODO candidate to be moved to ConfigParsingUtils -void AudioPolicyManager::loadHwModule(cnode *root) -{ - status_t status = NAME_NOT_FOUND; - cnode *node; - sp module = new HwModule(root->name); - - node = config_find(root, DEVICES_TAG); - if (node != NULL) { - node = node->first_child; - while (node) { - ALOGV("loadHwModule() loading device %s", node->name); - status_t tmpStatus = module->loadDevice(node); - if (status == NAME_NOT_FOUND || status == NO_ERROR) { - status = tmpStatus; - } - node = node->next; - } - } - node = config_find(root, OUTPUTS_TAG); - if (node != NULL) { - node = node->first_child; - while (node) { - ALOGV("loadHwModule() loading output %s", node->name); - status_t tmpStatus = module->loadOutput(node); - if (status == NAME_NOT_FOUND || status == NO_ERROR) { - status = tmpStatus; - } - node = node->next; - } - } - node = config_find(root, INPUTS_TAG); - if (node != NULL) { - node = node->first_child; - while (node) { - ALOGV("loadHwModule() loading input %s", node->name); - status_t tmpStatus = module->loadInput(node); - if (status == NAME_NOT_FOUND || status == NO_ERROR) { - status = tmpStatus; - } - node = node->next; - } - } - loadGlobalConfig(root, module); - - if (status == NO_ERROR) { - mHwModules.add(module); - } -} - -// TODO candidate to be moved to ConfigParsingUtils -void AudioPolicyManager::loadHwModules(cnode *root) -{ - cnode *node = config_find(root, AUDIO_HW_MODULE_TAG); - if (node == NULL) { - return; - } - - node = node->first_child; - while (node) { - ALOGV("loadHwModules() loading module %s", node->name); - loadHwModule(node); - node = node->next; - } -} - -// TODO candidate to be moved to ConfigParsingUtils -void AudioPolicyManager::loadGlobalConfig(cnode *root, const sp& module) -{ - cnode *node = config_find(root, GLOBAL_CONFIG_TAG); - - if (node == NULL) { - return; - } - DeviceVector declaredDevices; - if (module != NULL) { - declaredDevices = module->mDeclaredDevices; - } - - node = node->first_child; - while (node) { - if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) { - mAvailableOutputDevices.loadDevicesFromName((char *)node->value, - declaredDevices); - ALOGV("loadGlobalConfig() Attached Output Devices %08x", - mAvailableOutputDevices.types()); - } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) { - audio_devices_t device = (audio_devices_t)ConfigParsingUtils::stringToEnum( - sDeviceNameToEnumTable, - ARRAY_SIZE(sDeviceNameToEnumTable), - (char *)node->value); - if (device != AUDIO_DEVICE_NONE) { - mDefaultOutputDevice = new DeviceDescriptor(String8("default-output"), device); - } else { - ALOGW("loadGlobalConfig() default device not specified"); - } - ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType); - } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) { - mAvailableInputDevices.loadDevicesFromName((char *)node->value, - declaredDevices); - ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types()); - } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) { - mSpeakerDrcEnabled = ConfigParsingUtils::stringToBool((char *)node->value); - ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled); - } else if (strcmp(AUDIO_HAL_VERSION_TAG, node->name) == 0) { - uint32_t major, minor; - sscanf((char *)node->value, "%u.%u", &major, &minor); - module->mHalVersion = HARDWARE_DEVICE_API_VERSION(major, minor); - ALOGV("loadGlobalConfig() mHalVersion = %04x major %u minor %u", - module->mHalVersion, major, minor); - } - node = node->next; - } -} - -// TODO candidate to be moved to ConfigParsingUtils -status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path) -{ - cnode *root; - char *data; - - data = (char *)load_file(path, NULL); - if (data == NULL) { - return -ENODEV; - } - root = config_node("", ""); - config_load(root, data); - - loadHwModules(root); - // legacy audio_policy.conf files have one global_configuration section - loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY)); - config_free(root); - free(root); - free(data); - - ALOGI("loadAudioPolicyConfig() loaded %s\n", path); - - return NO_ERROR; -} - void AudioPolicyManager::defaultAudioPolicyConfig(void) { sp module; @@ -5717,7 +5271,8 @@ audio_stream_type_t AudioPolicyManager::streamTypefromAttributesInt(const audio_ } } -bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa) { +bool AudioPolicyManager::isValidAttributes(const audio_attributes_t *paa) +{ // has flags that map to a strategy? if ((paa->flags & (AUDIO_FLAG_AUDIBILITY_ENFORCED | AUDIO_FLAG_SCO | AUDIO_FLAG_BEACON)) != 0) { return true; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index 279dc93..ce9c69c 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -160,13 +160,19 @@ public: virtual status_t unregisterEffect(int id); virtual status_t setEffectEnabled(int id, bool enabled); - virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const; + virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const + { + return mOutputs.isStreamActive(stream, inPastMs); + } // return whether a stream is playing remotely, override to change the definition of // local/remote playback, used for instance by notification manager to not make // media players lose audio focus when not playing locally // For the base implementation, "remotely" means playing during screen mirroring which // uses an output for playback with a non-empty, non "0" address. - virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const; + virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const + { + return mOutputs.isStreamActiveRemotely(stream, inPastMs); + } virtual bool isSourceActive(audio_source_t source) const; virtual status_t dump(int fd); @@ -201,10 +207,6 @@ public: // Audio policy configuration file parsing (audio_policy.conf) // TODO candidates to be moved to ConfigParsingUtils - void loadHwModule(cnode *root); - void loadHwModules(cnode *root); - void loadGlobalConfig(cnode *root, const sp& module); - status_t loadAudioPolicyConfig(const char *path); void defaultAudioPolicyConfig(void); // return the strategy corresponding to a given stream type @@ -225,6 +227,7 @@ protected: }; void addOutput(audio_io_handle_t output, sp outputDesc); + void removeOutput(audio_io_handle_t output); void addInput(audio_io_handle_t input, sp inputDesc); // return appropriate device for streams handled by the specified strategy according to current @@ -262,13 +265,6 @@ protected: // select input device corresponding to requested audio source virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource); - // return io handle of active input or 0 if no input is active - // Only considers inputs from physical devices (e.g. main mic, headset mic) when - // ignoreVirtualInputs is true. - audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true); - - uint32_t activeInputsCount() const; - // initialize volume curves for each strategy and device category void initializeVolumeCurves(); @@ -344,9 +340,6 @@ protected: // manages A2DP output suspend/restore according to phone state and BT SCO usage void checkA2dpSuspend(); - // returns the A2DP output handle if it is open or 0 otherwise - audio_io_handle_t getA2dpOutput(); - // selects the most appropriate device on output for current state // must be called every time a condition that affects the device choice for a given output is // changed: connected device, phone state, force use, output start, output stop.. @@ -374,7 +367,7 @@ protected: status_t setEffectEnabled(const sp& effectDesc, bool enabled); SortedVector getOutputsForDevice(audio_devices_t device, - DefaultKeyedVector > openOutputs); + AudioOutputCollection openOutputs); bool vectorsEqual(SortedVector& outputs1, SortedVector& outputs2); @@ -406,29 +399,36 @@ protected: bool isNonOffloadableEffectEnabled(); - virtual status_t addAudioPatch(audio_patch_handle_t handle, - const sp& patch); - virtual status_t removeAudioPatch(audio_patch_handle_t handle); + virtual status_t addAudioPatch(audio_patch_handle_t handle, const sp& patch) + { + return mAudioPatches.addAudioPatch(handle, patch); + } + virtual status_t removeAudioPatch(audio_patch_handle_t handle) + { + return mAudioPatches.removeAudioPatch(handle); + } - sp getOutputFromId(audio_port_handle_t id) const; - sp getInputFromId(audio_port_handle_t id) const; - sp getModuleForDevice(audio_devices_t device) const; - sp getModuleFromName(const char *name) const; - audio_devices_t availablePrimaryOutputDevices(); - audio_devices_t availablePrimaryInputDevices(); + audio_devices_t availablePrimaryOutputDevices() const + { + return mOutputs.getSupportedDevices(mPrimaryOutput) & mAvailableOutputDevices.types(); + } + audio_devices_t availablePrimaryInputDevices() const + { + return mAvailableInputDevices.getDevicesFromHwModule( + mOutputs.valueFor(mPrimaryOutput)->getModuleHandle()); + } void updateCallRouting(audio_devices_t rxDevice, int delayMs = 0); - uid_t mUidCached; AudioPolicyClientInterface *mpClientInterface; // audio policy client interface audio_io_handle_t mPrimaryOutput; // primary output handle // list of descriptors for outputs currently opened - DefaultKeyedVector > mOutputs; + AudioOutputCollection mOutputs; // copy of mOutputs before setDeviceConnectionState() opens new outputs // reset to mOutputs when updateDevicesAndOutputs() is called. - DefaultKeyedVector > mPreviousOutputs; - DefaultKeyedVector > mInputs; // list of input descriptors + AudioOutputCollection mPreviousOutputs; + AudioInputCollection mInputs; // list of input descriptors DeviceVector mAvailableOutputDevices; // all available output devices DeviceVector mAvailableInputDevices; // all available input devices int mPhoneState; // current phone state @@ -451,10 +451,11 @@ protected: bool mSpeakerDrcEnabled;// true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path // to boost soft sounds, used to adjust volume curves accordingly - Vector < sp > mHwModules; + HwModuleCollection mHwModules; + volatile int32_t mAudioPortGeneration; - DefaultKeyedVector > mAudioPatches; + AudioPatchCollection mAudioPatches; DefaultKeyedVector mSoundTriggerSessions; @@ -499,14 +500,11 @@ protected: uint32_t mTestLatencyMs; #endif //AUDIO_POLICY_TEST - static bool isVirtualInputDevice(audio_devices_t device); - uint32_t nextAudioPortGeneration(); private: // updates device caching and output for streams that can influence the // routing of notifications void handleNotificationRoutingForStream(audio_stream_type_t stream); - static bool deviceDistinguishesOnAddress(audio_devices_t device); // find the outputs on a given output descriptor that have the given address. // to be called on an AudioOutputDescriptor whose supported devices (as defined // in mProfile->mSupportedDevices) matches the device whose address is to be matched. @@ -529,8 +527,6 @@ private: const audio_offload_info_t *offloadInfo); // internal function to derive a stream type value from audio attributes audio_stream_type_t streamTypefromAttributesInt(const audio_attributes_t *attr); - // return true if any output is playing anything besides the stream to ignore - bool isAnyOutputActive(audio_stream_type_t streamToIgnore); // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON // returns 0 if no mute/unmute event happened, the largest latency of the device where // the mute/unmute happened @@ -548,9 +544,6 @@ private: audio_policy_dev_state_t state, const char *device_address, const char *device_name); - sp getDeviceDescriptor(const audio_devices_t device, - const char *device_address, - const char *device_name); bool isStrategyActive(const sp outputDesc, routing_strategy strategy, uint32_t inPastMs = 0, nsecs_t sysTime = 0) const; -- cgit v1.1