1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "daudio_adapter_internal.h"
17
18 #include <securec.h>
19 #include <string>
20
21 #include <v1_0/iaudio_render.h>
22 #include <v1_0/iaudio_capture.h>
23 #include <v1_0/audio_types.h>
24
25 #include "daudio_errorcode.h"
26 #include "daudio_log.h"
27
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "DAudioAdapterInternal"
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 using namespace OHOS::HDI::DistributedAudio::Audio::V1_0;
34
InitAllPortsInternal(struct AudioAdapter * adapter)35 static int32_t InitAllPortsInternal(struct AudioAdapter *adapter)
36 {
37 if (adapter == nullptr) {
38 DHLOGE("The parameter is empty.");
39 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
40 }
41 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
42 if (context->proxy_ == nullptr) {
43 DHLOGE("The context or proxy for the context is nullptr.");
44 return ERR_DH_AUDIO_HDI_NULLPTR;
45 }
46 return context->proxy_->InitAllPorts();
47 }
48
SetAudioSampleAttributesHAL(const struct::AudioSampleAttributes * attrs,AudioSampleAttributes & attrsHal)49 static void SetAudioSampleAttributesHAL(const struct ::AudioSampleAttributes *attrs,
50 AudioSampleAttributes &attrsHal)
51 {
52 attrsHal.type = static_cast<AudioCategory>(attrs->type);
53 attrsHal.interleaved = attrs->interleaved;
54 attrsHal.format = static_cast<AudioFormat>(attrs->format);
55 attrsHal.sampleRate = attrs->sampleRate;
56 attrsHal.channelCount = attrs->channelCount;
57 attrsHal.period = attrs->period;
58 attrsHal.frameSize = attrs->frameSize;
59 attrsHal.isBigEndian = attrs->isBigEndian;
60 attrsHal.isSignedData = attrs->isSignedData;
61 attrsHal.startThreshold = attrs->startThreshold;
62 attrsHal.stopThreshold = attrs->stopThreshold;
63 attrsHal.silenceThreshold = attrs->silenceThreshold;
64 attrsHal.streamId = attrs->streamId;
65 }
66
CreateRenderInternal(struct AudioAdapter * adapter,const struct::AudioDeviceDescriptor * desc,const struct::AudioSampleAttributes * attrs,struct AudioRender ** render)67 static int32_t CreateRenderInternal(struct AudioAdapter *adapter, const struct ::AudioDeviceDescriptor *desc,
68 const struct ::AudioSampleAttributes *attrs, struct AudioRender **render)
69 {
70 DHLOGI("Create distributed audio render.");
71 if (adapter == nullptr || desc == nullptr || attrs == nullptr || render == nullptr) {
72 DHLOGE("The parameter is empty.");
73 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
74 }
75
76 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
77 if (context->proxy_ == nullptr) {
78 DHLOGE("The context or proxy for the context is nullptr.");
79 return ERR_DH_AUDIO_HDI_NULLPTR;
80 }
81 AudioDeviceDescriptor descHal = {
82 .portId = desc->portId,
83 .pins = static_cast<AudioPortPin>(desc->pins),
84 };
85 descHal.desc = desc->desc == nullptr ? "" : desc->desc;
86
87 AudioSampleAttributes attrsHal;
88 SetAudioSampleAttributesHAL(attrs, attrsHal);
89 sptr<IAudioRender> renderProxy = nullptr;
90 int32_t ret = context->proxy_->CreateRender(descHal, attrsHal, renderProxy);
91 if (ret != DH_SUCCESS) {
92 *render = nullptr;
93 return ret;
94 }
95 auto renderContext = std::make_unique<AudioRenderContext>();
96 *render = &renderContext->instance_;
97 renderContext->proxy_ = renderProxy;
98 renderContext->descHal_ = descHal;
99 {
100 std::lock_guard<std::mutex> lock(context->mtx_);
101 context->renders_.push_back(std::move(renderContext));
102 }
103 return DH_SUCCESS;
104 }
105
DestroyRenderInternal(struct AudioAdapter * adapter,struct AudioRender * render)106 static int32_t DestroyRenderInternal(struct AudioAdapter *adapter, struct AudioRender *render)
107 {
108 DHLOGI("Destroy distributed audio render.");
109 if (adapter == nullptr || render == nullptr) {
110 DHLOGE("The parameter is empty.");
111 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
112 }
113
114 AudioAdapterContext *adapterContext = reinterpret_cast<AudioAdapterContext *>(adapter);
115 AudioRenderContext *renderContext = reinterpret_cast<AudioRenderContext *>(render);
116 if (adapterContext->proxy_ == nullptr) {
117 DHLOGE("The adapter context or proxy for the adapter context is nullptr.");
118 return ERR_DH_AUDIO_HDI_NULLPTR;
119 }
120 std::lock_guard<std::mutex> lock(adapterContext->mtx_);
121
122 for (auto it = adapterContext->renders_.begin(); it != adapterContext->renders_.end(); ++it) {
123 if ((*it).get() == renderContext) {
124 int32_t ret = adapterContext->proxy_->DestroyRender(renderContext->descHal_);
125 if (ret != DH_SUCCESS) {
126 return ret;
127 }
128 adapterContext->renders_.erase(it);
129 break;
130 }
131 }
132 return DH_SUCCESS;
133 }
134
CreateCaptureInternal(struct AudioAdapter * adapter,const struct::AudioDeviceDescriptor * desc,const struct::AudioSampleAttributes * attrs,struct AudioCapture ** capture)135 static int32_t CreateCaptureInternal(struct AudioAdapter *adapter, const struct ::AudioDeviceDescriptor *desc,
136 const struct ::AudioSampleAttributes *attrs, struct AudioCapture **capture)
137 {
138 DHLOGI("Create distributed audio capture.");
139 if (adapter == nullptr || desc == nullptr || attrs == nullptr || capture == nullptr) {
140 DHLOGE("The parameter is empty.");
141 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
142 }
143
144 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
145 if (context->proxy_ == nullptr) {
146 DHLOGE("The context or proxy for the context is nullptr.");
147 return ERR_DH_AUDIO_HDI_NULLPTR;
148 }
149 AudioDeviceDescriptor descHal = {
150 .portId = desc->portId,
151 .pins = static_cast<AudioPortPin>(desc->pins),
152 };
153 descHal.desc = desc->desc == nullptr ? "" : desc->desc;
154 AudioSampleAttributes attrsHal;
155 SetAudioSampleAttributesHAL(attrs, attrsHal);
156 sptr<IAudioCapture> captureProxy = nullptr;
157 int32_t ret = context->proxy_->CreateCapture(descHal, attrsHal, captureProxy);
158 if (ret != DH_SUCCESS) {
159 *capture = nullptr;
160 return ret;
161 }
162
163 auto captureContext = std::make_unique<AudioCaptureContext>();
164 *capture = &captureContext->instance_;
165 captureContext->proxy_ = captureProxy;
166 captureContext->descHal_ = descHal;
167 {
168 std::lock_guard<std::mutex> lock(context->mtx_);
169 context->captures_.push_back(std::move(captureContext));
170 }
171 return DH_SUCCESS;
172 }
173
DestroyCaptureInternal(struct AudioAdapter * adapter,struct AudioCapture * capture)174 static int32_t DestroyCaptureInternal(struct AudioAdapter *adapter, struct AudioCapture *capture)
175 {
176 DHLOGI("Destroy distributed audio capture.");
177 if (adapter == nullptr || capture == nullptr) {
178 DHLOGE("The parameter is empty.");
179 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
180 }
181
182 AudioAdapterContext *adapterContext = reinterpret_cast<AudioAdapterContext *>(adapter);
183 AudioCaptureContext *captureContext = reinterpret_cast<AudioCaptureContext *>(capture);
184 if (adapterContext->proxy_ == nullptr) {
185 DHLOGE("The adapter context or proxy for the adapter context is nullptr.");
186 return ERR_DH_AUDIO_HDI_NULLPTR;
187 }
188 std::lock_guard<std::mutex> lock(adapterContext->mtx_);
189
190 for (auto it = adapterContext->captures_.begin(); it != adapterContext->captures_.end(); ++it) {
191 if ((*it).get() == captureContext) {
192 int32_t ret = adapterContext->proxy_->DestroyCapture(captureContext->descHal_);
193 if (ret != DH_SUCCESS) {
194 return ret;
195 }
196 adapterContext->captures_.erase(it);
197 break;
198 }
199 }
200 return DH_SUCCESS;
201 }
202
GetPassthroughModeInternal(struct AudioAdapter * adapter,const struct::AudioPort * port,enum::AudioPortPassthroughMode * mode)203 static int32_t GetPassthroughModeInternal(struct AudioAdapter *adapter, const struct ::AudioPort *port,
204 enum ::AudioPortPassthroughMode *mode)
205 {
206 if (adapter == nullptr || port == nullptr || mode == nullptr) {
207 DHLOGE("The parameter is empty.");
208 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
209 }
210
211 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
212 if (context->proxy_ == nullptr) {
213 DHLOGE("The context or proxy for the context is nullptr.");
214 return ERR_DH_AUDIO_HDI_NULLPTR;
215 }
216 AudioPort portHal = {
217 .dir = static_cast<AudioPortDirection>(port->dir),
218 .portId = port->portId,
219 .portName= port->portName,
220 };
221 return context->proxy_->GetPassthroughMode(portHal, *(reinterpret_cast<AudioPortPassthroughMode *>(mode)));
222 }
223
InitAudioPortCapability(std::unique_ptr<::AudioPortCapability> & capInternal,AudioPortCapability & capabilityHal)224 static int32_t InitAudioPortCapability(std::unique_ptr<::AudioPortCapability> &capInternal,
225 AudioPortCapability &capabilityHal)
226 {
227 DHLOGI("Init audio port capability internal, formatNum: %zu.", capabilityHal.formatNum);
228 constexpr uint32_t maxFormatNum = 100;
229 constexpr uint32_t minFormatNum = 1;
230 if (capabilityHal.formatNum < minFormatNum || capabilityHal.formatNum > maxFormatNum) {
231 DHLOGE("Init audio port capability, formatNum: %zu.", capabilityHal.formatNum);
232 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
233 }
234 ::AudioFormat *audioFormats = (::AudioFormat *)malloc(capabilityHal.formatNum * sizeof(::AudioFormat));
235 if (audioFormats == nullptr) {
236 DHLOGE("Malloc failed.");
237 return ERR_DH_AUDIO_HDI_CALL_FAILED;
238 }
239
240 capInternal->deviceType = capabilityHal.deviceType;
241 capInternal->deviceId = capabilityHal.deviceId;
242 capInternal->hardwareMode = static_cast<bool>(capabilityHal.hardwareMode);
243 capInternal->formatNum = capabilityHal.formatNum;
244 capInternal->formats = audioFormats;
245 for (auto format : capabilityHal.formats) {
246 *audioFormats = static_cast<::AudioFormat>(format);
247 audioFormats++;
248 }
249 capInternal->sampleRateMasks = capabilityHal.sampleRateMasks;
250 capInternal->channelMasks = static_cast<::AudioChannelMask>(capabilityHal.channelMasks);
251 capInternal->channelCount = capabilityHal.channelCount;
252 capInternal->subPortsNum = 0;
253 capInternal->subPorts = nullptr;
254 return DH_SUCCESS;
255 }
256
GetPortCapabilityInternal(struct AudioAdapter * adapter,const struct::AudioPort * port,struct::AudioPortCapability * capability)257 static int32_t GetPortCapabilityInternal(struct AudioAdapter *adapter, const struct ::AudioPort *port,
258 struct ::AudioPortCapability *capability)
259 {
260 if (adapter == nullptr || port == nullptr || port->portName == nullptr || capability == nullptr) {
261 DHLOGE("The parameter is empty.");
262 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
263 }
264
265 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
266 if (context->proxy_ == nullptr) {
267 DHLOGE("The context or proxy for the context is nullptr.");
268 return ERR_DH_AUDIO_HDI_NULLPTR;
269 }
270 {
271 std::lock_guard<std::mutex> lock(context->mtx_);
272 auto iter = context->caps_.find(port->portId);
273 if (iter != context->caps_.end()) {
274 *capability = *(iter->second);
275 return DH_SUCCESS;
276 }
277 }
278 AudioPort portHal = {
279 .dir = static_cast<AudioPortDirection>(port->dir),
280 .portId = port->portId,
281 .portName = port->portName,
282 };
283
284 AudioPortCapability capabilityHal;
285 int32_t ret = context->proxy_->GetPortCapability(portHal, capabilityHal);
286 if (ret != DH_SUCCESS) {
287 return ret;
288 }
289
290 auto capInternal = std::make_unique<::AudioPortCapability>();
291 ret = InitAudioPortCapability(capInternal, capabilityHal);
292 if (ret != DH_SUCCESS) {
293 return ret;
294 }
295 *capability = *capInternal;
296 {
297 std::lock_guard<std::mutex> lock(context->mtx_);
298 context->caps_[port->portId] = std::move(capInternal);
299 }
300 return DH_SUCCESS;
301 }
302
ReleaseAudioRouteInternal(struct AudioAdapter * adapter,int32_t routeHandle)303 static int32_t ReleaseAudioRouteInternal(struct AudioAdapter *adapter, int32_t routeHandle)
304 {
305 if (adapter == nullptr) {
306 DHLOGE("The parameter is empty.");
307 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
308 }
309
310 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
311 if (context->proxy_ == nullptr) {
312 DHLOGE("The context or proxy for the context is nullptr.");
313 return ERR_DH_AUDIO_HDI_NULLPTR;
314 }
315 return context->proxy_->ReleaseAudioRoute(routeHandle);
316 }
317
SetPassthroughModeInternal(struct AudioAdapter * adapter,const struct::AudioPort * port,enum::AudioPortPassthroughMode mode)318 static int32_t SetPassthroughModeInternal(struct AudioAdapter *adapter, const struct ::AudioPort *port,
319 enum ::AudioPortPassthroughMode mode)
320 {
321 if (adapter == nullptr || port == nullptr) {
322 DHLOGE("The parameter is empty.");
323 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
324 }
325
326 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
327 if (context->proxy_ == nullptr) {
328 DHLOGE("The context or proxy for the context is nullptr.");
329 return ERR_DH_AUDIO_HDI_NULLPTR;
330 }
331 AudioPort portHal = {
332 .dir = static_cast<AudioPortDirection>(port->dir),
333 .portId = port->portId,
334 .portName = port->portName,
335 };
336 AudioPortPassthroughMode modeHal = static_cast<AudioPortPassthroughMode>(static_cast<int32_t>(mode));
337 return context->proxy_->SetPassthroughMode(portHal, modeHal);
338 }
339
ConvertAudioRouteNodeToHAL(const::AudioRouteNode & node,AudioRouteNode & halNode)340 static void ConvertAudioRouteNodeToHAL(const ::AudioRouteNode &node, AudioRouteNode &halNode)
341 {
342 halNode.portId = node.portId;
343 halNode.role = static_cast<AudioPortRole>(node.role);
344 halNode.type = static_cast<AudioPortType>(node.type);
345 DHLOGD("Convert audio route node To HAL, portId: %d role: %d type: %d.", halNode.portId, halNode.role,
346 halNode.type);
347
348 switch (node.type) {
349 case AUDIO_PORT_UNASSIGNED_TYPE:
350 break;
351 case AUDIO_PORT_DEVICE_TYPE: {
352 size_t descLength = DESCRIPTOR_LENGTH;
353 halNode.ext.device.moduleId = node.ext.device.moduleId;
354 halNode.ext.device.type = static_cast<AudioPortPin>(node.ext.device.type);
355 if (node.ext.device.desc != nullptr) {
356 size_t length = strlen(node.ext.device.desc);
357 length = length < descLength ? length : descLength;
358 halNode.ext.device.desc = std::string(node.ext.device.desc, node.ext.device.desc + length);
359 }
360 break;
361 }
362 case AUDIO_PORT_MIX_TYPE: {
363 halNode.ext.mix.moduleId = node.ext.mix.moduleId;
364 halNode.ext.mix.streamId = node.ext.mix.streamId;
365
366 DHLOGD("Convert audio route node To HAL, [Mix] moduleId: %d streamId: %d.",
367 halNode.ext.mix.moduleId, halNode.ext.mix.streamId);
368 break;
369 }
370 case AUDIO_PORT_SESSION_TYPE: {
371 halNode.ext.session.sessionType = static_cast<AudioSessionType>(node.ext.session.sessionType);
372 DHLOGD("Convert audio route node To HAL, [Session] sessionType: %d.", halNode.ext.session.sessionType);
373 break;
374 }
375 default :
376 DHLOGD("Unknown node Type");
377 }
378 }
UpdateAudioRouteInternal(struct AudioAdapter * adapter,const struct::AudioRoute * route,int32_t * routeHandle)379 static int32_t UpdateAudioRouteInternal(struct AudioAdapter *adapter, const struct ::AudioRoute *route,
380 int32_t *routeHandle)
381 {
382 if (adapter == nullptr || route == nullptr || routeHandle == nullptr) {
383 DHLOGE("The parameter is empty.");
384 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
385 }
386
387 AudioRoute audioRoute;
388 for (uint32_t i = 0; i < route->sourcesNum; ++i) {
389 AudioRouteNode halNode = {0};
390 ConvertAudioRouteNodeToHAL(route->sources[i], halNode);
391 audioRoute.sources.push_back(halNode);
392 }
393
394 for (uint32_t i = 0; i < route->sinksNum; ++i) {
395 AudioRouteNode halNode = {0};
396 ConvertAudioRouteNodeToHAL(route->sinks[i], halNode);
397 audioRoute.sinks.push_back(halNode);
398 }
399
400 int32_t handle = -1;
401 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
402 if (context->proxy_ == nullptr) {
403 DHLOGE("The context or proxy for the context is nullptr.");
404 return ERR_DH_AUDIO_HDI_NULLPTR;
405 }
406 int32_t ret = context->proxy_->UpdateAudioRoute(audioRoute, handle);
407 *routeHandle = handle;
408 return ret;
409 }
410
SetExtraParamsInternal(struct AudioAdapter * adapter,enum::AudioExtParamKey key,const char * condition,const char * value)411 static int32_t SetExtraParamsInternal(struct AudioAdapter *adapter, enum ::AudioExtParamKey key,
412 const char *condition, const char *value)
413 {
414 if (adapter == nullptr || condition == nullptr || value == nullptr) {
415 DHLOGE("The parameter is empty.");
416 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
417 }
418
419 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
420 if (context->proxy_ == nullptr) {
421 DHLOGE("The context or proxy for the context is nullptr.");
422 return ERR_DH_AUDIO_HDI_NULLPTR;
423 }
424 return context->proxy_->SetExtraParams(static_cast<AudioExtParamKey>(key),
425 std::string(condition), std::string(value));
426 }
427
GetExtraParamsInternal(struct AudioAdapter * adapter,enum::AudioExtParamKey key,const char * condition,char * value,int32_t length)428 static int32_t GetExtraParamsInternal(struct AudioAdapter *adapter, enum ::AudioExtParamKey key,
429 const char *condition, char *value, int32_t length)
430 {
431 if (adapter == nullptr || condition == nullptr || value == nullptr) {
432 DHLOGE("The parameter is empty.");
433 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
434 }
435
436 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
437 if (context->proxy_ == nullptr) {
438 DHLOGE("The context or proxy for the context is nullptr.");
439 return ERR_DH_AUDIO_HDI_NULLPTR;
440 }
441 std::string valueHal;
442 int32_t ret =
443 context->proxy_->GetExtraParams(static_cast<AudioExtParamKey>(key),
444 std::string(condition), valueHal);
445 if (ret != DH_SUCCESS) {
446 return ret;
447 }
448 ret = strcpy_s(value, length, valueHal.c_str());
449 if (ret != EOK) {
450 DHLOGE("Strcpy_s failed!, ret: %d", ret);
451 return ERR_DH_AUDIO_HDI_CALL_FAILED;
452 }
453 return DH_SUCCESS;
454 }
455
RegExtraParamObserverInternal(struct AudioAdapter * adapter,ParamCallback callback,void * cookie)456 static int32_t RegExtraParamObserverInternal(struct AudioAdapter *adapter, ParamCallback callback, void* cookie)
457 {
458 if (adapter == nullptr || callback == nullptr) {
459 DHLOGE("The parameter is empty.");
460 return ERR_DH_AUDIO_HDI_INVALID_PARAM;
461 }
462
463 AudioAdapterContext *context = reinterpret_cast<AudioAdapterContext *>(adapter);
464 if (context->proxy_ == nullptr) {
465 DHLOGE("The context or proxy for the context is nullptr.");
466 return ERR_DH_AUDIO_HDI_NULLPTR;
467 }
468 std::lock_guard<std::mutex> lock(context->mtx_);
469 if (context->callbackInternal_ == nullptr || callback != context->callback_) {
470 context->callbackInternal_ = std::make_unique<AudioParamCallbackContext>(callback, cookie);
471 } else {
472 return DH_SUCCESS;
473 }
474
475 if (context->callbackInternal_->callbackStub_ == nullptr) {
476 context->callbackInternal_ = nullptr;
477 return ERR_DH_AUDIO_HDI_CALL_FAILED;
478 }
479
480 int32_t ret = context->proxy_->RegExtraParamObserver(context->callbackInternal_->callbackStub_, 0);
481 if (ret == DH_SUCCESS) {
482 context->callback_ = callback;
483 } else {
484 context->callbackInternal_ = nullptr;
485 }
486
487 return ret;
488 }
489
AudioAdapterContext()490 AudioAdapterContext::AudioAdapterContext()
491 {
492 instance_.InitAllPorts = InitAllPortsInternal;
493 instance_.CreateRender = CreateRenderInternal;
494 instance_.DestroyRender = DestroyRenderInternal;
495 instance_.CreateCapture = CreateCaptureInternal;
496 instance_.DestroyCapture = DestroyCaptureInternal;
497 instance_.GetPassthroughMode = GetPassthroughModeInternal;
498 instance_.GetPortCapability = GetPortCapabilityInternal;
499 instance_.ReleaseAudioRoute = ReleaseAudioRouteInternal;
500 instance_.SetPassthroughMode = SetPassthroughModeInternal;
501 instance_.UpdateAudioRoute = UpdateAudioRouteInternal;
502 instance_.SetExtraParams = SetExtraParamsInternal;
503 instance_.GetExtraParams = GetExtraParamsInternal;
504 instance_.RegExtraParamObserver = RegExtraParamObserverInternal;
505
506 instance_.SetVoiceVolume = nullptr;
507 instance_.GetMicMute = nullptr;
508 instance_.SetMicMute = nullptr;
509 instance_.GetDeviceStatus = nullptr;
510 }
511
~AudioAdapterContext()512 AudioAdapterContext::~AudioAdapterContext()
513 {
514 captures_.clear();
515 renders_.clear();
516 for (auto &cap : caps_) {
517 if (cap.second->formats != nullptr) {
518 free(cap.second->formats);
519 }
520 }
521 caps_.clear();
522 }
523 } // namespace DistributedHardware
524 } // namespace OHOS
525