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