1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <stdlib.h> 20 #include <stdio.h> 21 #include <string.h> 22 #include <future> 23 24 #include <android-base/thread_annotations.h> 25 #include <audio_utils/mutex.h> 26 #include <cutils/misc.h> 27 #include <media/AudioEffect.h> 28 #include <media/audiohal/EffectsFactoryHalInterface.h> 29 #include <system/audio.h> 30 #include <utils/Vector.h> 31 #include <utils/SortedVector.h> 32 33 namespace android { 34 35 // ---------------------------------------------------------------------------- 36 37 /** 38 * AudioPolicyEffects class. 39 * 40 * This class manages all effects attached to input and output streams in AudioPolicyService. 41 * The effect configurations can be queried in several ways: 42 * 43 * With HIDL HAL, the configuration file `audio_effects.xml` will be loaded by libAudioHal. If this 44 * file does not exist, AudioPolicyEffects class will fallback to load configuration from 45 * `/vendor/etc/audio_effects.conf` (AUDIO_EFFECT_VENDOR_CONFIG_FILE). If this file also does not 46 * exist, the configuration will be loaded from the file `/system/etc/audio_effects.conf`. 47 * 48 * With AIDL HAL, the configuration will be queried with the method `IFactory::queryProcessing()`. 49 */ 50 class AudioPolicyEffects : public RefBase 51 { 52 53 public: 54 55 // The constructor will parse audio_effects.conf 56 // First it will look whether vendor specific file exists, 57 // otherwise it will parse the system default file. 58 explicit AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& effectsFactoryHal); 59 60 // NOTE: methods on AudioPolicyEffects should never be called with the AudioPolicyService 61 // main mutex (mMutex) held as they will indirectly call back into AudioPolicyService when 62 // managing audio effects. 63 64 // Return a list of effect descriptors for default input effects 65 // associated with audioSession 66 status_t queryDefaultInputEffects(audio_session_t audioSession, 67 effect_descriptor_t *descriptors, 68 uint32_t* count) EXCLUDES_AudioPolicyEffects_Mutex; 69 70 // Add all input effects associated with this input 71 // Effects are attached depending on the audio_source_t 72 status_t addInputEffects(audio_io_handle_t input, 73 audio_source_t inputSource, 74 audio_session_t audioSession) EXCLUDES_AudioPolicyEffects_Mutex; 75 76 // Add all input effects associated to this input 77 status_t releaseInputEffects(audio_io_handle_t input, 78 audio_session_t audioSession) EXCLUDES_AudioPolicyEffects_Mutex; 79 80 // Return a list of effect descriptors for default output effects 81 // associated with audioSession 82 status_t queryDefaultOutputSessionEffects(audio_session_t audioSession, 83 effect_descriptor_t *descriptors, 84 uint32_t* count) EXCLUDES_AudioPolicyEffects_Mutex; 85 86 // Add all output effects associated to this output 87 // Effects are attached depending on the audio_stream_type_t 88 status_t addOutputSessionEffects(audio_io_handle_t output, 89 audio_stream_type_t stream, 90 audio_session_t audioSession) EXCLUDES_AudioPolicyEffects_Mutex; 91 92 // release all output effects associated with this output stream and audiosession 93 status_t releaseOutputSessionEffects(audio_io_handle_t output, 94 audio_stream_type_t stream, 95 audio_session_t audioSession) EXCLUDES_AudioPolicyEffects_Mutex; 96 97 // Add the effect to the list of default effects for sources of type |source|. 98 status_t addSourceDefaultEffect(const effect_uuid_t *type, 99 const String16& opPackageName, 100 const effect_uuid_t *uuid, 101 int32_t priority, 102 audio_source_t source, 103 audio_unique_id_t* id) EXCLUDES_AudioPolicyEffects_Mutex; 104 105 // Add the effect to the list of default effects for streams of a given usage. 106 status_t addStreamDefaultEffect(const effect_uuid_t *type, 107 const String16& opPackageName, 108 const effect_uuid_t *uuid, 109 int32_t priority, 110 audio_usage_t usage, 111 audio_unique_id_t* id) EXCLUDES_AudioPolicyEffects_Mutex; 112 113 // Remove the default source effect from wherever it's attached. 114 status_t removeSourceDefaultEffect(audio_unique_id_t id) EXCLUDES_AudioPolicyEffects_Mutex; 115 116 // Remove the default stream effect from wherever it's attached. 117 status_t removeStreamDefaultEffect(audio_unique_id_t id) EXCLUDES_AudioPolicyEffects_Mutex; 118 119 // Initializes the Effects (AudioSystem must be ready as this creates audio client objects). 120 void initDefaultDeviceEffects() EXCLUDES(mDeviceEffectsMutex) EXCLUDES_EffectHandle_Mutex; 121 122 private: 123 124 // class to store the description of an effects and its parameters 125 // as defined in audio_effects.conf 126 class EffectDesc { 127 public: EffectDesc(std::string_view name,const effect_uuid_t & typeUuid,const String16 & opPackageName,const effect_uuid_t & uuid,uint32_t priority,audio_unique_id_t id)128 EffectDesc(std::string_view name, 129 const effect_uuid_t& typeUuid, 130 const String16& opPackageName, 131 const effect_uuid_t& uuid, 132 uint32_t priority, 133 audio_unique_id_t id) : 134 mName(name), 135 mTypeUuid(typeUuid), 136 mOpPackageName(opPackageName), 137 mUuid(uuid), 138 mPriority(priority), 139 mId(id) { } 140 // Modern EffectDesc usage: EffectDesc(std::string_view name,const effect_uuid_t & uuid)141 EffectDesc(std::string_view name, const effect_uuid_t& uuid) : 142 EffectDesc(name, 143 *EFFECT_UUID_NULL, 144 String16(""), 145 uuid, 146 0, 147 AUDIO_UNIQUE_ID_ALLOCATE) { } EffectDesc(const EffectDesc & orig)148 EffectDesc(const EffectDesc& orig) : 149 mName(orig.mName), 150 mTypeUuid(orig.mTypeUuid), 151 mOpPackageName(orig.mOpPackageName), 152 mUuid(orig.mUuid), 153 mPriority(orig.mPriority), 154 mId(orig.mId), 155 mParams(orig.mParams) { } 156 157 const std::string mName; 158 const effect_uuid_t mTypeUuid; 159 const String16 mOpPackageName; 160 const effect_uuid_t mUuid; 161 const int32_t mPriority; 162 const audio_unique_id_t mId; 163 std::vector<std::shared_ptr<const effect_param_t>> mParams; 164 }; 165 166 using EffectDescVector = std::vector<std::shared_ptr<EffectDesc>>; 167 168 class EffectVector { 169 public: EffectVector(audio_session_t session)170 explicit EffectVector(audio_session_t session) : mSessionId(session) {} 171 172 // Enable or disable all effects in effect vector 173 void setProcessorEnabled(bool enabled); 174 175 const audio_session_t mSessionId; 176 // AudioPolicyManager keeps mMutex, no need for lock on reference count here 177 int mRefCount = 0; 178 std::vector<sp<AudioEffect>> mEffects; 179 }; 180 181 /** 182 * @brief The DeviceEffects class stores the effects associated to a given Device Port. 183 */ 184 class DeviceEffects { 185 public: DeviceEffects(std::unique_ptr<EffectDescVector> effectDescriptors,audio_devices_t device,std::string_view address)186 DeviceEffects(std::unique_ptr<EffectDescVector> effectDescriptors, 187 audio_devices_t device, std::string_view address) : 188 mEffectDescriptors(std::move(effectDescriptors)), 189 mDeviceType(device), mDeviceAddress(address) {} 190 191 std::vector<sp<AudioEffect>> mEffects; getDeviceType()192 audio_devices_t getDeviceType() const { return mDeviceType; } getDeviceAddress()193 std::string getDeviceAddress() const { return mDeviceAddress; } 194 const std::unique_ptr<EffectDescVector> mEffectDescriptors; 195 196 private: 197 const audio_devices_t mDeviceType; 198 const std::string mDeviceAddress; 199 200 }; 201 202 status_t loadAudioEffectConfig_ll(const sp<EffectsFactoryHalInterface>& effectsFactoryHal) 203 REQUIRES(mMutex, mDeviceEffectsMutex); 204 205 // Legacy: Begin methods below. 206 // Parse audio_effects.conf - called from constructor. 207 status_t loadAudioEffectConfigLegacy_l(const char* path) REQUIRES(mMutex); 208 209 // Legacy: Load all automatic effect configurations 210 status_t loadInputEffectConfigurations_l(cnode* root, 211 const EffectDescVector& effects) REQUIRES(mMutex); 212 status_t loadStreamEffectConfigurations_l(cnode* root, 213 const EffectDescVector& effects) REQUIRES(mMutex); 214 215 // Legacy: static methods below. 216 217 static audio_source_t inputSourceNameToEnum(const char *name); 218 219 static audio_stream_type_t streamNameToEnum(const char* name); 220 221 // Load all effects descriptors in configuration file 222 static EffectDescVector loadEffects(cnode* root); 223 static std::shared_ptr<AudioPolicyEffects::EffectDesc> loadEffect(cnode* root); 224 static std::shared_ptr<EffectDescVector> loadEffectConfig(cnode* root, 225 const EffectDescVector& effects); 226 227 // Load all automatic effect parameters 228 static void loadEffectParameters( 229 cnode* root, std::vector<std::shared_ptr<const effect_param_t>>& params); 230 231 // loadEffectParameter returns a shared_ptr instead of a unique_ptr as there may 232 // be multiple references to the same effect parameter. 233 static std::shared_ptr<const effect_param_t> loadEffectParameter(cnode* root); 234 static size_t readParamValue(cnode* node, 235 char **param, 236 size_t *curSize, 237 size_t *totSize); 238 static size_t growParamSize(char** param, 239 size_t size, 240 size_t *curSize, 241 size_t *totSize); 242 243 // Legacy: End methods above. 244 245 // Note: The association of Effects to audio source, session, or stream 246 // is done through std::map instead of std::unordered_map. This gives 247 // better reproducibility of issues, since map is ordered and more predictable 248 // in enumeration. 249 250 // protects access to mInputSources, mInputSessions, mOutputStreams, mOutputSessions 251 // never hold AudioPolicyService::mMutex when calling AudioPolicyEffects methods as 252 // those can call back into AudioPolicyService methods and try to acquire the mutex 253 mutable audio_utils::mutex mMutex{audio_utils::MutexOrder::kAudioPolicyEffects_Mutex}; 254 // Automatic input effects are configured per audio_source_t 255 std::map<audio_source_t, std::shared_ptr<EffectDescVector>> mInputSources 256 GUARDED_BY(mMutex); 257 // Automatic input effects are unique for an audio_session_t. 258 std::map<audio_session_t, std::shared_ptr<EffectVector>> mInputSessions 259 GUARDED_BY(mMutex); 260 261 // Automatic output effects are organized per audio_stream_type_t 262 std::map<audio_stream_type_t, std::shared_ptr<EffectDescVector>> mOutputStreams 263 GUARDED_BY(mMutex); 264 // Automatic output effects are unique for an audio_session_t. 265 std::map<audio_session_t, std::shared_ptr<EffectVector>> mOutputSessions 266 GUARDED_BY(mMutex); 267 268 /** 269 * @brief mDeviceEffects map of device effects indexed by the device address 270 */ 271 272 // mDeviceEffects is never accessed through AudioPolicyEffects methods. 273 // We keep a separate mutex here to catch future methods attempting to access this variable. 274 std::mutex mDeviceEffectsMutex; 275 std::map<std::string, std::unique_ptr<DeviceEffects>> mDeviceEffects 276 GUARDED_BY(mDeviceEffectsMutex); 277 }; 278 279 } // namespace android 280