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