1 /*
2  * Copyright (C) 2018 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 #ifndef ANDROID_HARDWARE_AUDIO_EFFECT_EFFECT_H
18 #define ANDROID_HARDWARE_AUDIO_EFFECT_EFFECT_H
19 
20 #include PATH(android/hardware/audio/effect/FILE_VERSION/IEffect.h)
21 
22 #include "AudioBufferManager.h"
23 
24 #include <atomic>
25 #include <memory>
26 #include <vector>
27 
28 #include <fmq/EventFlag.h>
29 #include <fmq/MessageQueue.h>
30 #include <hidl/MQDescriptor.h>
31 #include <hidl/Status.h>
32 #include <utils/Thread.h>
33 
34 #include <hardware/audio_effect.h>
35 
36 #include "VersionUtils.h"
37 
38 namespace android {
39 namespace hardware {
40 namespace audio {
41 namespace effect {
42 namespace CPP_VERSION {
43 namespace implementation {
44 
45 using ::android::sp;
46 using ::android::hardware::hidl_string;
47 using ::android::hardware::hidl_vec;
48 using ::android::hardware::Return;
49 using ::android::hardware::Void;
50 #if MAJOR_VERSION <= 6
51 using ::android::hardware::audio::common::CPP_VERSION::implementation::AudioDeviceBitfield;
52 #endif
53 using namespace ::android::hardware::audio::common::CPP_VERSION;
54 using namespace ::android::hardware::audio::effect::CPP_VERSION;
55 
56 struct Effect : public IEffect {
57     typedef MessageQueue<Result, kSynchronizedReadWrite> StatusMQ;
58     using GetParameterSuccessCallback =
59         std::function<void(uint32_t valueSize, const void* valueData)>;
60 
61     Effect(bool isInput, effect_handle_t handle);
62 
63     // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffect follow.
64     Return<Result> init() override;
65     Return<Result> setConfig(
66         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
67         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
68     Return<Result> reset() override;
69     Return<Result> enable() override;
70     Return<Result> disable() override;
71 #if MAJOR_VERSION <= 6
72     Return<Result> setAudioSource(AudioSource source) override;
73     Return<Result> setDevice(AudioDeviceBitfield device) override;
74     Return<Result> setInputDevice(AudioDeviceBitfield device) override;
75 #else
76     Return<Result> setAudioSource(const AudioSource& source) override;
77     Return<Result> setDevice(const DeviceAddress& device) override;
78     Return<Result> setInputDevice(const DeviceAddress& device) override;
79 #endif
80     Return<void> setAndGetVolume(const hidl_vec<uint32_t>& volumes,
81                                  setAndGetVolume_cb _hidl_cb) override;
82     Return<Result> volumeChangeNotification(const hidl_vec<uint32_t>& volumes) override;
83     Return<Result> setAudioMode(AudioMode mode) override;
84     Return<Result> setConfigReverse(
85         const EffectConfig& config, const sp<IEffectBufferProviderCallback>& inputBufferProvider,
86         const sp<IEffectBufferProviderCallback>& outputBufferProvider) override;
87     Return<void> getConfig(getConfig_cb _hidl_cb) override;
88     Return<void> getConfigReverse(getConfigReverse_cb _hidl_cb) override;
89     Return<void> getSupportedAuxChannelsConfigs(
90         uint32_t maxConfigs, getSupportedAuxChannelsConfigs_cb _hidl_cb) override;
91     Return<void> getAuxChannelsConfig(getAuxChannelsConfig_cb _hidl_cb) override;
92     Return<Result> setAuxChannelsConfig(const EffectAuxChannelsConfig& config) override;
93     Return<Result> offload(const EffectOffloadParameter& param) override;
94     Return<void> getDescriptor(getDescriptor_cb _hidl_cb) override;
95     Return<void> prepareForProcessing(prepareForProcessing_cb _hidl_cb) override;
96     Return<Result> setProcessBuffers(const AudioBuffer& inBuffer,
97                                      const AudioBuffer& outBuffer) override;
98     Return<void> command(uint32_t commandId, const hidl_vec<uint8_t>& data, uint32_t resultMaxSize,
99                          command_cb _hidl_cb) override;
100     Return<Result> setParameter(const hidl_vec<uint8_t>& parameter,
101                                 const hidl_vec<uint8_t>& value) override;
102     Return<void> getParameter(const hidl_vec<uint8_t>& parameter, uint32_t valueMaxSize,
103                               getParameter_cb _hidl_cb) override;
104     Return<void> getSupportedConfigsForFeature(uint32_t featureId, uint32_t maxConfigs,
105                                                uint32_t configSize,
106                                                getSupportedConfigsForFeature_cb _hidl_cb) override;
107     Return<void> getCurrentConfigForFeature(uint32_t featureId, uint32_t configSize,
108                                             getCurrentConfigForFeature_cb _hidl_cb) override;
109     Return<Result> setCurrentConfigForFeature(uint32_t featureId,
110                                               const hidl_vec<uint8_t>& configData) override;
111     Return<Result> close() override;
112     Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& options) override;
113 
114     // Utility methods for extending interfaces.
115     static const char* sContextConversion;
116 
117     Result analyzeStatus(const char* funcName, const char* subFuncName,
118                          const char* contextDescription, status_t status);
119     template <typename T>
getIntegerParamEffect120     Return<void> getIntegerParam(uint32_t paramId,
121                                  std::function<void(Result retval, T paramValue)> cb) {
122         T value;
123         Result retval = getParameterImpl(sizeof(uint32_t), &paramId, sizeof(T),
124                                          [&](uint32_t valueSize, const void* valueData) {
125                                              if (valueSize > sizeof(T)) valueSize = sizeof(T);
126                                              memcpy(&value, valueData, valueSize);
127                                          });
128         cb(retval, value);
129         return Void();
130     }
131 
132     template <typename T>
getParamEffect133     Result getParam(uint32_t paramId, T& paramValue) {
134         return getParameterImpl(sizeof(uint32_t), &paramId, sizeof(T),
135                                 [&](uint32_t valueSize, const void* valueData) {
136                                     if (valueSize > sizeof(T)) valueSize = sizeof(T);
137                                     memcpy(&paramValue, valueData, valueSize);
138                                 });
139     }
140 
141     template <typename T>
getParamEffect142     Result getParam(uint32_t paramId, uint32_t paramArg, T& paramValue) {
143         uint32_t params[2] = {paramId, paramArg};
144         return getParameterImpl(sizeof(params), params, sizeof(T),
145                                 [&](uint32_t valueSize, const void* valueData) {
146                                     if (valueSize > sizeof(T)) valueSize = sizeof(T);
147                                     memcpy(&paramValue, valueData, valueSize);
148                                 });
149     }
150 
151     template <typename T>
setParamEffect152     Result setParam(uint32_t paramId, const T& paramValue) {
153         return setParameterImpl(sizeof(uint32_t), &paramId, sizeof(T), &paramValue);
154     }
155 
156     template <typename T>
setParamEffect157     Result setParam(uint32_t paramId, uint32_t paramArg, const T& paramValue) {
158         uint32_t params[2] = {paramId, paramArg};
159         return setParameterImpl(sizeof(params), params, sizeof(T), &paramValue);
160     }
161 
getParameterImplEffect162     Result getParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
163                             GetParameterSuccessCallback onSuccess) {
164         return getParameterImpl(paramSize, paramData, valueSize, valueSize, onSuccess);
165     }
166     Result getParameterImpl(uint32_t paramSize, const void* paramData, uint32_t requestValueSize,
167                             uint32_t replyValueSize, GetParameterSuccessCallback onSuccess);
168     Result setParameterImpl(uint32_t paramSize, const void* paramData, uint32_t valueSize,
169                             const void* valueData);
170 
171    private:
172     friend struct VirtualizerEffect;  // for getParameterImpl
173     friend struct VisualizerEffect;   // to allow executing commands
174 
175     using CommandSuccessCallback = std::function<void()>;
176     using GetConfigCallback = std::function<void(Result retval, const EffectConfig& config)>;
177     using GetCurrentConfigSuccessCallback = std::function<void(void* configData)>;
178     using GetSupportedConfigsSuccessCallback =
179         std::function<void(uint32_t supportedConfigs, void* configsData)>;
180 
181     static const char* sContextResultOfCommand;
182     static const char* sContextCallToCommand;
183     static const char* sContextCallFunction;
184 
185     const bool mIsInput;
186     effect_handle_t mHandle;
187     sp<AudioBufferWrapper> mInBuffer;
188     sp<AudioBufferWrapper> mOutBuffer;
189     std::atomic<audio_buffer_t*> mHalInBufferPtr;
190     std::atomic<audio_buffer_t*> mHalOutBufferPtr;
191     std::unique_ptr<StatusMQ> mStatusMQ;
192     EventFlag* mEfGroup;
193     std::atomic<bool> mStopProcessThread;
194     sp<Thread> mProcessThread;
195 
196     virtual ~Effect();
197 
198     template <typename T>
199     static size_t alignedSizeIn(size_t s);
200     template <typename T>
201     std::unique_ptr<uint8_t[]> hidlVecToHal(const hidl_vec<T>& vec, uint32_t* halDataSize);
202     void effectAuxChannelsConfigFromHal(const channel_config_t& halConfig,
203                                         EffectAuxChannelsConfig* config);
204     static void effectAuxChannelsConfigToHal(const EffectAuxChannelsConfig& config,
205                                              channel_config_t* halConfig);
206     static void effectOffloadParamToHal(const EffectOffloadParameter& offload,
207                                         effect_offload_param_t* halOffload);
208     static std::vector<uint8_t> parameterToHal(uint32_t paramSize, const void* paramData,
209                                                uint32_t valueSize, const void** valueData);
210 
211     Result analyzeCommandStatus(const char* commandName, const char* context, status_t status);
212     void getConfigImpl(int commandCode, const char* commandName, GetConfigCallback cb);
213     Result getCurrentConfigImpl(uint32_t featureId, uint32_t configSize,
214                                 GetCurrentConfigSuccessCallback onSuccess);
215     Result getSupportedConfigsImpl(uint32_t featureId, uint32_t maxConfigs, uint32_t configSize,
216                                    GetSupportedConfigsSuccessCallback onSuccess);
217     Result sendCommand(int commandCode, const char* commandName);
218     Result sendCommand(int commandCode, const char* commandName, uint32_t size, void* data);
219     Result sendCommandReturningData(int commandCode, const char* commandName, uint32_t* replySize,
220                                     void* replyData);
221     Result sendCommandReturningData(int commandCode, const char* commandName, uint32_t size,
222                                     void* data, uint32_t* replySize, void* replyData);
223     Result sendCommandReturningStatus(int commandCode, const char* commandName);
224     Result sendCommandReturningStatus(int commandCode, const char* commandName, uint32_t size,
225                                       void* data);
226     Result sendCommandReturningStatusAndData(int commandCode, const char* commandName,
227                                              uint32_t size, void* data, uint32_t* replySize,
228                                              void* replyData, uint32_t minReplySize,
229                                              CommandSuccessCallback onSuccess);
230     Result setConfigImpl(int commandCode, const char* commandName, const EffectConfig& config,
231                          const sp<IEffectBufferProviderCallback>& inputBufferProvider,
232                          const sp<IEffectBufferProviderCallback>& outputBufferProvider);
233 };
234 
235 }  // namespace implementation
236 }  // namespace CPP_VERSION
237 }  // namespace effect
238 }  // namespace audio
239 }  // namespace hardware
240 }  // namespace android
241 
242 #endif  // ANDROID_HARDWARE_AUDIO_EFFECT_EFFECT_H
243