/* * Copyright (C) 2014 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. */ #ifndef ANDROID_AUDIOPOLICYEFFECTS_H #define ANDROID_AUDIOPOLICYEFFECTS_H #include #include #include #include #include #include #include #include #include #include namespace android { // ---------------------------------------------------------------------------- // AudioPolicyEffects class // This class will manage all effects attached to input and output streams in // AudioPolicyService as configured in audio_effects.conf. class AudioPolicyEffects : public RefBase { public: // The constructor will parse audio_effects.conf // First it will look whether vendor specific file exists, // otherwise it will parse the system default file. AudioPolicyEffects(); virtual ~AudioPolicyEffects(); // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService // main mutex (mLock) held as they will indirectly call back into AudioPolicyService when // managing audio effects. // Return a list of effect descriptors for default input effects // associated with audioSession status_t queryDefaultInputEffects(audio_session_t audioSession, effect_descriptor_t *descriptors, uint32_t *count); // Add all input effects associated with this input // Effects are attached depending on the audio_source_t status_t addInputEffects(audio_io_handle_t input, audio_source_t inputSource, audio_session_t audioSession); // Add all input effects associated to this input status_t releaseInputEffects(audio_io_handle_t input, audio_session_t audioSession); // Return a list of effect descriptors for default output effects // associated with audioSession status_t queryDefaultOutputSessionEffects(audio_session_t audioSession, effect_descriptor_t *descriptors, uint32_t *count); // Add all output effects associated to this output // Effects are attached depending on the audio_stream_type_t status_t addOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t audioSession); // release all output effects associated with this output stream and audiosession status_t releaseOutputSessionEffects(audio_io_handle_t output, audio_stream_type_t stream, audio_session_t audioSession); // Add the effect to the list of default effects for sources of type |source|. status_t addSourceDefaultEffect(const effect_uuid_t *type, const String16& opPackageName, const effect_uuid_t *uuid, int32_t priority, audio_source_t source, audio_unique_id_t* id); // Add the effect to the list of default effects for streams of a given usage. status_t addStreamDefaultEffect(const effect_uuid_t *type, const String16& opPackageName, const effect_uuid_t *uuid, int32_t priority, audio_usage_t usage, audio_unique_id_t* id); // Remove the default source effect from wherever it's attached. status_t removeSourceDefaultEffect(audio_unique_id_t id); // Remove the default stream effect from wherever it's attached. status_t removeStreamDefaultEffect(audio_unique_id_t id); private: void initDefaultDeviceEffects(); // class to store the description of an effects and its parameters // as defined in audio_effects.conf class EffectDesc { public: EffectDesc(const char *name, const effect_uuid_t& typeUuid, const String16& opPackageName, const effect_uuid_t& uuid, uint32_t priority, audio_unique_id_t id) : mName(strdup(name)), mTypeUuid(typeUuid), mOpPackageName(opPackageName), mUuid(uuid), mPriority(priority), mId(id) { } EffectDesc(const char *name, const effect_uuid_t& uuid) : EffectDesc(name, *EFFECT_UUID_NULL, String16(""), uuid, 0, AUDIO_UNIQUE_ID_ALLOCATE) { } EffectDesc(const EffectDesc& orig) : mName(strdup(orig.mName)), mTypeUuid(orig.mTypeUuid), mOpPackageName(orig.mOpPackageName), mUuid(orig.mUuid), mPriority(orig.mPriority), mId(orig.mId) { // deep copy mParams for (size_t k = 0; k < orig.mParams.size(); k++) { effect_param_t *origParam = orig.mParams[k]; // psize and vsize are rounded up to an int boundary for allocation size_t origSize = sizeof(effect_param_t) + ((origParam->psize + 3) & ~3) + ((origParam->vsize + 3) & ~3); effect_param_t *dupParam = (effect_param_t *) malloc(origSize); memcpy(dupParam, origParam, origSize); // This works because the param buffer allocation is also done by // multiples of 4 bytes originally. In theory we should memcpy only // the actual param size, that is without rounding vsize. mParams.add(dupParam); } } /*virtual*/ ~EffectDesc() { free(mName); for (size_t k = 0; k < mParams.size(); k++) { free(mParams[k]); } } char *mName; effect_uuid_t mTypeUuid; String16 mOpPackageName; effect_uuid_t mUuid; int32_t mPriority; audio_unique_id_t mId; Vector mParams; }; // class to store voctor of EffectDesc class EffectDescVector { public: EffectDescVector() {} /*virtual*/ ~EffectDescVector() { for (size_t j = 0; j < mEffects.size(); j++) { delete mEffects[j]; } } Vector mEffects; }; // class to store voctor of AudioEffects class EffectVector { public: explicit EffectVector(audio_session_t session) : mSessionId(session), mRefCount(0) {} /*virtual*/ ~EffectVector() {} // Enable or disable all effects in effect vector void setProcessorEnabled(bool enabled); const audio_session_t mSessionId; // AudioPolicyManager keeps mLock, no need for lock on reference count here int mRefCount; Vector< sp >mEffects; }; /** * @brief The DeviceEffects class stores the effects associated to a given Device Port. */ class DeviceEffects { public: DeviceEffects(std::unique_ptr effectDescriptors, audio_devices_t device, const std::string& address) : mEffectDescriptors(std::move(effectDescriptors)), mDeviceType(device), mDeviceAddress(address) {} /*virtual*/ ~DeviceEffects() = default; std::vector< sp > mEffects; audio_devices_t getDeviceType() const { return mDeviceType; } std::string getDeviceAddress() const { return mDeviceAddress; } const std::unique_ptr mEffectDescriptors; private: const audio_devices_t mDeviceType; const std::string mDeviceAddress; }; static const char * const kInputSourceNames[AUDIO_SOURCE_CNT -1]; static audio_source_t inputSourceNameToEnum(const char *name); static const char *kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1]; //+1 required as streams start from -1 audio_stream_type_t streamNameToEnum(const char *name); // Parse audio_effects.conf status_t loadAudioEffectConfig(const char *path); // TODO: add legacy in the name status_t loadAudioEffectXmlConfig(); // TODO: remove "Xml" in the name // Load all effects descriptors in configuration file status_t loadEffects(cnode *root, Vector & effects); EffectDesc *loadEffect(cnode *root); // Load all automatic effect configurations status_t loadInputEffectConfigurations(cnode *root, const Vector & effects); status_t loadStreamEffectConfigurations(cnode *root, const Vector & effects); EffectDescVector *loadEffectConfig(cnode *root, const Vector & effects); // Load all automatic effect parameters void loadEffectParameters(cnode *root, Vector & params); effect_param_t *loadEffectParameter(cnode *root); size_t readParamValue(cnode *node, char **param, size_t *curSize, size_t *totSize); size_t growParamSize(char **param, size_t size, size_t *curSize, size_t *totSize); // protects access to mInputSources, mInputSessions, mOutputStreams, mOutputSessions // never hold AudioPolicyService::mLock when calling AudioPolicyEffects methods as // those can call back into AudioPolicyService methods and try to acquire the mutex Mutex mLock; // Automatic input effects are configured per audio_source_t KeyedVector< audio_source_t, EffectDescVector* > mInputSources; // Automatic input effects are unique for audio_io_handle_t KeyedVector< audio_session_t, EffectVector* > mInputSessions; // Automatic output effects are organized per audio_stream_type_t KeyedVector< audio_stream_type_t, EffectDescVector* > mOutputStreams; // Automatic output effects are unique for audiosession ID KeyedVector< audio_session_t, EffectVector* > mOutputSessions; /** * @brief mDeviceEffects map of device effects indexed by the device address */ std::map> mDeviceEffects GUARDED_BY(mLock); /** * Device Effect initialization must be asynchronous: the audio_policy service parses and init * effect on first reference. AudioFlinger will handle effect creation and register these * effect on audio_policy service. * We must store the reference of the furture garantee real asynchronous operation. */ std::future mDefaultDeviceEffectFuture; }; } // namespace android #endif // ANDROID_AUDIOPOLICYEFFECTS_H