blob: 7e25b049f295ee0c6a60981aa28dfa63d76e85f7 [file] [log] [blame]
Shunkai Yao284bb0d2023-01-10 00:42:36 +00001/*
2 * Copyright (C) 2023 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 <cstdint>
18#include <cstring>
Shunkai Yao44bdbad2023-01-14 05:11:58 +000019#include <optional>
Shunkai Yao284bb0d2023-01-10 00:42:36 +000020#define LOG_TAG "EffectConversionHelperAidl"
21//#define LOG_NDEBUG 0
22
23#include <error/expected_utils.h>
Shunkai Yao242521c2023-01-29 18:08:09 +000024#include <media/AidlConversionCppNdk.h>
Shunkai Yaoa03533e2023-01-25 06:38:10 +000025#include <media/AidlConversionNdk.h>
26#include <media/AidlConversionEffect.h>
Shunkai Yao44bdbad2023-01-14 05:11:58 +000027
Shunkai Yao284bb0d2023-01-10 00:42:36 +000028#include <utils/Log.h>
29
30#include "EffectConversionHelperAidl.h"
31
32namespace android {
33namespace effect {
34
35using ::aidl::android::aidl_utils::statusTFromBinderStatus;
Shunkai Yao284bb0d2023-01-10 00:42:36 +000036using ::aidl::android::hardware::audio::effect::CommandId;
Shunkai Yao44bdbad2023-01-14 05:11:58 +000037using ::aidl::android::hardware::audio::effect::Descriptor;
Shunkai Yao284bb0d2023-01-10 00:42:36 +000038using ::aidl::android::hardware::audio::effect::Parameter;
39using ::aidl::android::media::audio::common::AudioDeviceDescription;
Shunkai Yao242521c2023-01-29 18:08:09 +000040using ::aidl::android::media::audio::common::AudioMode;
41using ::aidl::android::media::audio::common::AudioSource;
Shunkai Yao44bdbad2023-01-14 05:11:58 +000042using android::effect::utils::EffectParamReader;
43using android::effect::utils::EffectParamWriter;
Shunkai Yao284bb0d2023-01-10 00:42:36 +000044
45using ::android::status_t;
46
47const std::map<uint32_t /* effect_command_e */, EffectConversionHelperAidl::CommandHandler>
48 EffectConversionHelperAidl::mCommandHandlerMap = {
49 {EFFECT_CMD_INIT, &EffectConversionHelperAidl::handleInit},
50 {EFFECT_CMD_SET_PARAM, &EffectConversionHelperAidl::handleSetParameter},
51 {EFFECT_CMD_GET_PARAM, &EffectConversionHelperAidl::handleGetParameter},
52 {EFFECT_CMD_SET_CONFIG, &EffectConversionHelperAidl::handleSetConfig},
53 {EFFECT_CMD_GET_CONFIG, &EffectConversionHelperAidl::handleGetConfig},
54 {EFFECT_CMD_RESET, &EffectConversionHelperAidl::handleReset},
55 {EFFECT_CMD_ENABLE, &EffectConversionHelperAidl::handleEnable},
56 {EFFECT_CMD_DISABLE, &EffectConversionHelperAidl::handleDisable},
Shunkai Yao242521c2023-01-29 18:08:09 +000057 {EFFECT_CMD_SET_AUDIO_SOURCE, &EffectConversionHelperAidl::handleSetAudioSource},
Shunkai Yao284bb0d2023-01-10 00:42:36 +000058 {EFFECT_CMD_SET_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
59 {EFFECT_CMD_SET_INPUT_DEVICE, &EffectConversionHelperAidl::handleSetDevice},
60 {EFFECT_CMD_SET_VOLUME, &EffectConversionHelperAidl::handleSetVolume},
61 {EFFECT_CMD_OFFLOAD, &EffectConversionHelperAidl::handleSetOffload},
62 {EFFECT_CMD_FIRST_PROPRIETARY, &EffectConversionHelperAidl::handleFirstPriority}};
63
Shunkai Yao44bdbad2023-01-14 05:11:58 +000064EffectConversionHelperAidl::EffectConversionHelperAidl(
65 std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect> effect,
Shunkai Yaodba8ba32023-01-27 17:02:21 +000066 int32_t sessionId, int32_t ioId, const Descriptor& desc)
Shunkai Yao44bdbad2023-01-14 05:11:58 +000067 : mSessionId(sessionId), mIoId(ioId), mDesc(desc), mEffect(std::move(effect)) {
68 mCommon.session = sessionId;
69 mCommon.ioHandle = ioId;
70 mCommon.input = mCommon.output = kDefaultAudioConfig;
71}
Shunkai Yao284bb0d2023-01-10 00:42:36 +000072
73status_t EffectConversionHelperAidl::handleCommand(uint32_t cmdCode, uint32_t cmdSize,
74 void* pCmdData, uint32_t* replySize,
75 void* pReplyData) {
76 const auto& handler = mCommandHandlerMap.find(cmdCode);
77 if (handler == mCommandHandlerMap.end() || !handler->second) {
78 ALOGE("%s handler for command %u doesn't exist", __func__, cmdCode);
79 return BAD_VALUE;
80 }
81 return (this->*handler->second)(cmdSize, pCmdData, replySize, pReplyData);
82}
83
84status_t EffectConversionHelperAidl::handleInit(uint32_t cmdSize __unused,
85 const void* pCmdData __unused, uint32_t* replySize,
86 void* pReplyData) {
87 if (!replySize || *replySize < sizeof(int) || !pReplyData) {
88 return BAD_VALUE;
89 }
90
Shunkai Yao44bdbad2023-01-14 05:11:58 +000091 return *(status_t*)pReplyData =
92 statusTFromBinderStatus(mEffect->open(mCommon, std::nullopt, &mOpenReturn));
Shunkai Yao284bb0d2023-01-10 00:42:36 +000093}
94
95status_t EffectConversionHelperAidl::handleSetParameter(uint32_t cmdSize, const void* pCmdData,
96 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +000097 if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize ||
98 *replySize < sizeof(int) || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +000099 return BAD_VALUE;
100 }
101
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000102 auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
103 if (!reader.validateCmdSize(cmdSize)) {
104 ALOGE("%s illegal param %s size %u", __func__, reader.toString().c_str(), cmdSize);
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000105 return BAD_VALUE;
106 }
107
Shunkai Yao242521c2023-01-29 18:08:09 +0000108 status_t ret = setParameter(reader);
109 EffectParamWriter writer(*(effect_param_t*)pReplyData);
110 writer.setStatus(ret);
111 return *(status_t*)pReplyData = ret;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000112}
113
114status_t EffectConversionHelperAidl::handleGetParameter(uint32_t cmdSize, const void* pCmdData,
115 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000116 if (cmdSize < sizeof(effect_param_t) || !pCmdData || !replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000117 return BAD_VALUE;
118 }
119
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000120 const auto reader = EffectParamReader(*(effect_param_t*)pCmdData);
Shunkai Yao242521c2023-01-29 18:08:09 +0000121 if (*replySize < sizeof(effect_param_t) + reader.getParameterSize()) {
122 ALOGE("%s illegal param %s, replySize %u", __func__, reader.toString().c_str(), *replySize);
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000123 return BAD_VALUE;
124 }
125
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000126 // copy effect_param_t and parameters
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000127 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + reader.getParameterSize());
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000128 auto writer = EffectParamWriter(*(effect_param_t*)pReplyData);
129 status_t ret = getParameter(writer);
130 writer.finishValueWrite();
Shunkai Yao242521c2023-01-29 18:08:09 +0000131 writer.setStatus(ret);
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000132 *replySize = writer.getTotalSize();
Shunkai Yao242521c2023-01-29 18:08:09 +0000133 if (ret != OK) {
134 ALOGE("%s error ret %d, %s", __func__, ret, writer.toString().c_str());
135 }
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000136 return ret;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000137}
138
Shunkai Yao3ecc3eb2023-02-08 19:50:16 +0000139status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize,
140 const void* pCmdData __unused,
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000141 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000142 if (!replySize || *replySize != sizeof(int) || !pReplyData ||
143 cmdSize != sizeof(effect_config_t)) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000144 return BAD_VALUE;
145 }
146
Shunkai Yao3ecc3eb2023-02-08 19:50:16 +0000147 // TODO: need to implement setConfig with setParameter(common)
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000148 return *static_cast<int32_t*>(pReplyData) = OK;
149}
150
151status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
152 const void* pCmdData __unused,
153 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000154 if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000155 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
156 return BAD_VALUE;
157 }
158
159 Parameter param;
160 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(
161 Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common), &param)));
162
163 const auto& common = param.get<Parameter::common>();
164 effect_config_t* pConfig = (effect_config_t*)pReplyData;
165 pConfig->inputCfg = VALUE_OR_RETURN_STATUS(
166 ::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(common.input.base, true));
167 pConfig->outputCfg =
168 VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
169 common.output.base, false));
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000170 mCommon = common;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000171 return OK;
172}
173
174status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
175 const void* pCmdData __unused, uint32_t* replySize,
176 void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000177 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000178 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
179 return BAD_VALUE;
180 }
181
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000182 return statusTFromBinderStatus(mEffect->command(CommandId::RESET));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000183}
184
185status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
Shunkai Yao242521c2023-01-29 18:08:09 +0000186 const void* pCmdData __unused,
187 uint32_t* replySize, void* pReplyData) {
188 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000189 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
190 return BAD_VALUE;
191 }
192
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000193 return statusTFromBinderStatus(mEffect->command(CommandId::START));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000194}
195
196status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
197 const void* pCmdData __unused,
198 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000199 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000200 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
201 return BAD_VALUE;
202 }
203
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000204 return statusTFromBinderStatus(mEffect->command(CommandId::STOP));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000205}
206
Shunkai Yao242521c2023-01-29 18:08:09 +0000207status_t EffectConversionHelperAidl::handleSetAudioSource(uint32_t cmdSize, const void* pCmdData,
208 uint32_t* replySize, void* pReplyData) {
209 if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
210 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
211 pReplyData);
212 return BAD_VALUE;
213 }
214
215 audio_source_t source = *(audio_source_t*)pCmdData;
216 AudioSource aidlSource =
217 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_source_t_AudioSource(source));
218 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
219 mEffect->setParameter(Parameter::make<Parameter::source>(aidlSource))));
220 return *static_cast<int32_t*>(pReplyData) = OK;
221}
222
223status_t EffectConversionHelperAidl::handleSetAudioMode(uint32_t cmdSize, const void* pCmdData,
224 uint32_t* replySize, void* pReplyData) {
225 if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
226 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
227 pReplyData);
228 return BAD_VALUE;
229 }
230 audio_mode_t mode = *(audio_mode_t *)pCmdData;
231 AudioMode aidlMode =
232 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
233 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
234 mEffect->setParameter(Parameter::make<Parameter::mode>(aidlMode))));
235 return *static_cast<int32_t*>(pReplyData) = OK;
236}
237
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000238status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
239 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000240 if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000241 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
242 pReplyData);
243 return BAD_VALUE;
244 }
245 // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
246 // const auto& legacyDevice = *(uint32_t*)(pCmdData);
247 std::vector<AudioDeviceDescription> aidlDevices;
248 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
249 mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
250 return *static_cast<int32_t*>(pReplyData) = OK;
251}
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000252status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
253 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000254 if (cmdSize != 2 * sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000255 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
256 pReplyData);
257 return BAD_VALUE;
258 }
259 Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
260 .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
261 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
262 mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
263 return *static_cast<int32_t*>(pReplyData) = OK;
264}
265
266status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
267 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000268 if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000269 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
270 pReplyData);
271 return BAD_VALUE;
272 }
273 // TODO: handle this after effectproxy implemented in libaudiohal
274 return *static_cast<int32_t*>(pReplyData) = OK;
275}
276
277status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
278 const void* pCmdData __unused,
279 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000280 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000281 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
282 return BAD_VALUE;
283 }
284
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000285 // TODO to be implemented
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000286 return OK;
287}
288
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000289} // namespace effect
290} // namespace android