blob: 619059689a8f8844fc8dbeb7f72bc4dd59c7c53b [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
139status_t EffectConversionHelperAidl::handleSetConfig(uint32_t cmdSize, const void* pCmdData,
140 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000141 if (!replySize || *replySize != sizeof(int) || !pReplyData ||
142 cmdSize != sizeof(effect_config_t)) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000143 return BAD_VALUE;
144 }
145
Shunkai Yao242521c2023-01-29 18:08:09 +0000146 return *static_cast<int32_t*>(pReplyData) = OK;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000147 const auto& legacyConfig = static_cast<const effect_config_t*>(pCmdData);
148 // already open, apply latest settings
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000149 Parameter::Common common;
150 common.input.base =
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000151 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
152 legacyConfig->inputCfg, true /* isInput */));
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000153 common.output.base =
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000154 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_buffer_config_t_AudioConfigBase(
155 legacyConfig->outputCfg, false /* isInput */));
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000156 common.session = mSessionId;
157 common.ioHandle = mIoId;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000158 // TODO: add access mode support
159 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000160 mEffect->setParameter(Parameter::make<Parameter::common>(common))));
161 mCommon = common;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000162 return *static_cast<int32_t*>(pReplyData) = OK;
163}
164
165status_t EffectConversionHelperAidl::handleGetConfig(uint32_t cmdSize __unused,
166 const void* pCmdData __unused,
167 uint32_t* replySize, void* pReplyData) {
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000168 if (!replySize || *replySize != sizeof(effect_config_t) || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000169 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
170 return BAD_VALUE;
171 }
172
173 Parameter param;
174 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(
175 Parameter::Id::make<Parameter::Id::commonTag>(Parameter::common), &param)));
176
177 const auto& common = param.get<Parameter::common>();
178 effect_config_t* pConfig = (effect_config_t*)pReplyData;
179 pConfig->inputCfg = VALUE_OR_RETURN_STATUS(
180 ::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(common.input.base, true));
181 pConfig->outputCfg =
182 VALUE_OR_RETURN_STATUS(::aidl::android::aidl2legacy_AudioConfigBase_buffer_config_t(
183 common.output.base, false));
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000184 mCommon = common;
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000185 return OK;
186}
187
188status_t EffectConversionHelperAidl::handleReset(uint32_t cmdSize __unused,
189 const void* pCmdData __unused, uint32_t* replySize,
190 void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000191 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000192 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
193 return BAD_VALUE;
194 }
195
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000196 return statusTFromBinderStatus(mEffect->command(CommandId::RESET));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000197}
198
199status_t EffectConversionHelperAidl::handleEnable(uint32_t cmdSize __unused,
Shunkai Yao242521c2023-01-29 18:08:09 +0000200 const void* pCmdData __unused,
201 uint32_t* replySize, void* pReplyData) {
202 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000203 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
204 return BAD_VALUE;
205 }
206
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000207 return statusTFromBinderStatus(mEffect->command(CommandId::START));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000208}
209
210status_t EffectConversionHelperAidl::handleDisable(uint32_t cmdSize __unused,
211 const void* pCmdData __unused,
212 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000213 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000214 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
215 return BAD_VALUE;
216 }
217
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000218 return statusTFromBinderStatus(mEffect->command(CommandId::STOP));
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000219}
220
Shunkai Yao242521c2023-01-29 18:08:09 +0000221status_t EffectConversionHelperAidl::handleSetAudioSource(uint32_t cmdSize, const void* pCmdData,
222 uint32_t* replySize, void* pReplyData) {
223 if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
224 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
225 pReplyData);
226 return BAD_VALUE;
227 }
228
229 audio_source_t source = *(audio_source_t*)pCmdData;
230 AudioSource aidlSource =
231 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_source_t_AudioSource(source));
232 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
233 mEffect->setParameter(Parameter::make<Parameter::source>(aidlSource))));
234 return *static_cast<int32_t*>(pReplyData) = OK;
235}
236
237status_t EffectConversionHelperAidl::handleSetAudioMode(uint32_t cmdSize, const void* pCmdData,
238 uint32_t* replySize, void* pReplyData) {
239 if (cmdSize != sizeof(uint32_t) || !pCmdData || !replySize || !pReplyData) {
240 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
241 pReplyData);
242 return BAD_VALUE;
243 }
244 audio_mode_t mode = *(audio_mode_t *)pCmdData;
245 AudioMode aidlMode =
246 VALUE_OR_RETURN_STATUS(::aidl::android::legacy2aidl_audio_mode_t_AudioMode(mode));
247 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
248 mEffect->setParameter(Parameter::make<Parameter::mode>(aidlMode))));
249 return *static_cast<int32_t*>(pReplyData) = OK;
250}
251
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000252status_t EffectConversionHelperAidl::handleSetDevice(uint32_t cmdSize, const void* pCmdData,
253 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000254 if (cmdSize != 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 // TODO: convert from audio_devices_t to std::vector<AudioDeviceDescription>
260 // const auto& legacyDevice = *(uint32_t*)(pCmdData);
261 std::vector<AudioDeviceDescription> aidlDevices;
262 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
263 mEffect->setParameter(Parameter::make<Parameter::deviceDescription>(aidlDevices))));
264 return *static_cast<int32_t*>(pReplyData) = OK;
265}
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000266status_t EffectConversionHelperAidl::handleSetVolume(uint32_t cmdSize, const void* pCmdData,
267 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000268 if (cmdSize != 2 * sizeof(uint32_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 Parameter::VolumeStereo volume = {.left = (float)(*(uint32_t*)pCmdData) / (1 << 24),
274 .right = (float)(*(uint32_t*)pCmdData + 1) / (1 << 24)};
275 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
276 mEffect->setParameter(Parameter::make<Parameter::volumeStereo>(volume))));
277 return *static_cast<int32_t*>(pReplyData) = OK;
278}
279
280status_t EffectConversionHelperAidl::handleSetOffload(uint32_t cmdSize, const void* pCmdData,
281 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000282 if (cmdSize < sizeof(effect_offload_param_t) || !pCmdData || !replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000283 ALOGE("%s parameter invalid %u %p %p %p", __func__, cmdSize, pCmdData, replySize,
284 pReplyData);
285 return BAD_VALUE;
286 }
287 // TODO: handle this after effectproxy implemented in libaudiohal
288 return *static_cast<int32_t*>(pReplyData) = OK;
289}
290
291status_t EffectConversionHelperAidl::handleFirstPriority(uint32_t cmdSize __unused,
292 const void* pCmdData __unused,
293 uint32_t* replySize, void* pReplyData) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000294 if (!replySize || !pReplyData) {
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000295 ALOGE("%s parameter invalid %p %p", __func__, replySize, pReplyData);
296 return BAD_VALUE;
297 }
298
Shunkai Yao44bdbad2023-01-14 05:11:58 +0000299 // TODO to be implemented
Shunkai Yao284bb0d2023-01-10 00:42:36 +0000300 return OK;
301}
302
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000303} // namespace effect
304} // namespace android