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