1 /*
2 * Copyright (c) 2023-2025 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 #ifndef LOG_TAG
16 #define LOG_TAG "NapiAudioCapturer"
17 #endif
18
19 #include "napi_audio_capturer.h"
20 #ifdef FEATURE_HIVIEW_ENABLE
21 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
22 #include "xpower_event_js.h"
23 #endif
24 #endif
25 #include "audio_errors.h"
26 #include "napi_audio_error.h"
27 #include "napi_param_utils.h"
28 #include "napi_audio_enum.h"
29 #include "napi_audio_capturer_callbacks.h"
30 #include "napi_capturer_position_callback.h"
31 #include "napi_capturer_period_position_callback.h"
32 #include "napi_audio_capturer_read_data_callback.h"
33 #include "napi_audio_capturer_device_change_callback.h"
34 #include "napi_audio_capturer_info_change_callback.h"
35
36 namespace OHOS {
37 namespace AudioStandard {
38 static __thread napi_ref g_capturerConstructor = nullptr;
39 std::unique_ptr<AudioCapturerOptions> NapiAudioCapturer::sCapturerOptions_ = nullptr;
40 mutex NapiAudioCapturer::createMutex_;
41 int32_t NapiAudioCapturer::isConstructSuccess_ = SUCCESS;
42
NapiAudioCapturer()43 NapiAudioCapturer::NapiAudioCapturer()
44 : audioCapturer_(nullptr), sourceType_(SOURCE_TYPE_MIC), env_(nullptr) {}
45
~NapiAudioCapturer()46 NapiAudioCapturer::~NapiAudioCapturer()
47 {
48 if (audioCapturer_ != nullptr) {
49 bool ret = audioCapturer_->Release();
50 CHECK_AND_RETURN_LOG(ret, "AudioCapturer release fail");
51 audioCapturer_ = nullptr;
52 AUDIO_INFO_LOG("Proactively release audioCapturer");
53 }
54 }
55
Destructor(napi_env env,void * nativeObject,void * finalizeHint)56 void NapiAudioCapturer::Destructor(napi_env env, void *nativeObject, void *finalizeHint)
57 {
58 if (nativeObject == nullptr) {
59 AUDIO_WARNING_LOG("Native object is null");
60 return;
61 }
62 auto obj = static_cast<NapiAudioCapturer *>(nativeObject);
63 if (obj != nullptr && obj->capturerReadDataCallbackNapi_ != nullptr) {
64 std::shared_ptr<NapiCapturerReadDataCallback> cb =
65 std::static_pointer_cast<NapiCapturerReadDataCallback>(obj->capturerReadDataCallbackNapi_);
66 cb->RemoveNapiCapturer();
67 }
68 ObjectRefMap<NapiAudioCapturer>::DecreaseRef(obj);
69 AUDIO_INFO_LOG("Decrease obj count");
70 }
71
InitAudioCapturer(napi_env env,napi_value & constructor)72 napi_status NapiAudioCapturer::InitAudioCapturer(napi_env env, napi_value &constructor)
73 {
74 AUDIO_DEBUG_LOG("NapiAudioCapturer::InitAudioCapturer()");
75 napi_property_descriptor audio_capturer_properties[] = {
76 DECLARE_NAPI_FUNCTION("getCapturerInfo", GetCapturerInfo),
77 DECLARE_NAPI_FUNCTION("getCapturerInfoSync", GetCapturerInfoSync),
78 DECLARE_NAPI_FUNCTION("getStreamInfo", GetStreamInfo),
79 DECLARE_NAPI_FUNCTION("getStreamInfoSync", GetStreamInfoSync),
80 DECLARE_NAPI_FUNCTION("start", Start),
81 DECLARE_NAPI_FUNCTION("read", Read),
82 DECLARE_NAPI_FUNCTION("getAudioTime", GetAudioTime),
83 DECLARE_NAPI_FUNCTION("getAudioTimeSync", GetAudioTimeSync),
84 DECLARE_NAPI_FUNCTION("stop", Stop),
85 DECLARE_NAPI_FUNCTION("release", Release),
86 DECLARE_NAPI_FUNCTION("getBufferSize", GetBufferSize),
87 DECLARE_NAPI_FUNCTION("getBufferSizeSync", GetBufferSizeSync),
88 DECLARE_NAPI_FUNCTION("getAudioStreamId", GetAudioStreamId),
89 DECLARE_NAPI_FUNCTION("getAudioStreamIdSync", GetAudioStreamIdSync),
90 DECLARE_NAPI_FUNCTION("getCurrentInputDevices", GetCurrentInputDevices),
91 DECLARE_NAPI_FUNCTION("getCurrentAudioCapturerChangeInfo", GetCurrentAudioCapturerChangeInfo),
92 DECLARE_NAPI_FUNCTION("getCurrentMicrophones", GetCurrentMicrophones),
93 DECLARE_NAPI_FUNCTION("getOverflowCount", GetOverflowCount),
94 DECLARE_NAPI_FUNCTION("setInputDeviceToAccessory", SetInputDeviceToAccessory),
95 DECLARE_NAPI_FUNCTION("getOverflowCountSync", GetOverflowCountSync),
96 DECLARE_NAPI_FUNCTION("getAudioTimestampInfo", GetAudioTimestampInfo),
97 DECLARE_NAPI_FUNCTION("getAudioTimestampInfoSync", GetAudioTimestampInfoSync),
98 DECLARE_NAPI_FUNCTION("setWillMuteWhenInterrupted", SetWillMuteWhenInterrupted),
99 DECLARE_NAPI_FUNCTION("on", On),
100 DECLARE_NAPI_FUNCTION("off", Off),
101 DECLARE_NAPI_GETTER("state", GetState),
102 };
103
104 napi_status status = napi_define_class(env, NAPI_AUDIO_CAPTURER_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Construct,
105 nullptr, sizeof(audio_capturer_properties) / sizeof(audio_capturer_properties[PARAM0]),
106 audio_capturer_properties, &constructor);
107 return status;
108 }
109
Init(napi_env env,napi_value exports)110 napi_value NapiAudioCapturer::Init(napi_env env, napi_value exports)
111 {
112 napi_value constructor;
113 napi_value result = nullptr;
114 napi_get_undefined(env, &result);
115
116 napi_property_descriptor static_prop[] = {
117 DECLARE_NAPI_STATIC_FUNCTION("createAudioCapturer", CreateAudioCapturer),
118 DECLARE_NAPI_STATIC_FUNCTION("createAudioCapturerSync", CreateAudioCapturerSync)
119 };
120
121 napi_status status = InitAudioCapturer(env, constructor);
122 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_define_class fail");
123 status = napi_create_reference(env, constructor, REFERENCE_CREATION_COUNT, &g_capturerConstructor);
124 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_create_reference fail");
125 status = napi_set_named_property(env, exports, NAPI_AUDIO_CAPTURER_CLASS_NAME.c_str(), constructor);
126 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "napi_set_named_property fail");
127 status = napi_define_properties(env, exports, sizeof(static_prop) / sizeof(static_prop[0]), static_prop);
128 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "Failure in NapiAudioCapturer::Init()");
129
130 return exports;
131 }
132
CreateAudioCapturerNativeObject(napi_env env)133 unique_ptr<NapiAudioCapturer> NapiAudioCapturer::CreateAudioCapturerNativeObject(napi_env env)
134 {
135 unique_ptr<NapiAudioCapturer> napiCapturer = make_unique<NapiAudioCapturer>();
136 CHECK_AND_RETURN_RET_LOG(napiCapturer != nullptr, nullptr, "No memory");
137
138 napiCapturer->env_ = env;
139 napiCapturer->sourceType_ = sCapturerOptions_->capturerInfo.sourceType;
140
141 AudioCapturerOptions capturerOptions = *sCapturerOptions_;
142
143 /* NapiAudioCapturer not support other capturerFlags, only support flag 0 */
144 if (capturerOptions.capturerInfo.capturerFlags != 0) {
145 capturerOptions.capturerInfo.capturerFlags = 0;
146 }
147 capturerOptions.capturerInfo.recorderType = RECORDER_TYPE_ARKTS_AUDIO_RECORDER;
148 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
149 napiCapturer->audioCapturer_ = AudioCapturer::CreateCapturer(capturerOptions);
150 #else
151 std::string cacheDir = "/data/storage/el2/base/temp";
152 napiCapturer->audioCapturer_ = AudioCapturer::Create(capturerOptions, cacheDir);
153 #endif
154 if (napiCapturer->audioCapturer_ == nullptr) {
155 AUDIO_ERR_LOG("Capturer Create failed");
156 NapiAudioCapturer::isConstructSuccess_ = NAPI_ERR_SYSTEM;
157 napiCapturer.release();
158 return nullptr;
159 }
160 ObjectRefMap<NapiAudioCapturer>::Insert(napiCapturer.get());
161
162 if (napiCapturer->audioCapturer_ != nullptr && napiCapturer->callbackNapi_ == nullptr) {
163 napiCapturer->callbackNapi_ = std::make_shared<NapiAudioCapturerCallback>(env);
164 CHECK_AND_RETURN_RET_LOG(napiCapturer->callbackNapi_ != nullptr, napiCapturer, "No memory");
165 int32_t ret = napiCapturer->audioCapturer_->SetCapturerCallback(napiCapturer->callbackNapi_);
166 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, napiCapturer, "Construct SetCapturerCallback failed");
167 }
168 return napiCapturer;
169 }
170
GetCallback(size_t argc,napi_value * argv)171 napi_value NapiAudioCapturer::GetCallback(size_t argc, napi_value *argv)
172 {
173 napi_value callback = nullptr;
174
175 if (argc == ARGS_TWO) {
176 callback = argv[PARAM1];
177 }
178 return callback;
179 }
180
181 template <typename T>
GetCapturerNapiCallback(napi_value callback,const std::string & cbName,std::list<std::shared_ptr<NapiAudioCapturerCallbackInner>> audioCapturerCallbacks,std::shared_ptr<T> * cb)182 static void GetCapturerNapiCallback(napi_value callback, const std::string &cbName,
183 std::list<std::shared_ptr<NapiAudioCapturerCallbackInner>> audioCapturerCallbacks, std::shared_ptr<T> *cb)
184 {
185 if (audioCapturerCallbacks.size() == 0) {
186 AUDIO_ERR_LOG("no callback to get");
187 return;
188 }
189 for (auto &iter:audioCapturerCallbacks) {
190 if (!iter->CheckIfTargetCallbackName(cbName)) {
191 continue;
192 }
193 std::shared_ptr<T> temp = std::static_pointer_cast<T>(iter);
194 if (temp->ContainSameJsCallbackInner(cbName, callback)) {
195 *cb = temp;
196 return;
197 }
198 }
199 }
200
201 template <typename T>
UnregisterAudioCapturerSingletonCallbackTemplate(napi_env env,napi_value callback,const std::string & cbName,std::shared_ptr<T> cb,std::function<int32_t (std::shared_ptr<T> callbackPtr,napi_value callback)> removeFunction=nullptr)202 static void UnregisterAudioCapturerSingletonCallbackTemplate(napi_env env, napi_value callback,
203 const std::string &cbName, std::shared_ptr<T> cb,
204 std::function<int32_t(std::shared_ptr<T> callbackPtr, napi_value callback)> removeFunction = nullptr)
205 {
206 if (callback != nullptr) {
207 CHECK_AND_RETURN_LOG(cb->ContainSameJsCallbackInner(cbName, callback), "napi_get_cb_info failed");
208 }
209
210 cb->RemoveCallbackReference(cbName, env, callback);
211
212 if (removeFunction == nullptr) {
213 return;
214 }
215 int32_t ret = removeFunction(cb, callback);
216 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Unset of Capturer callback failed");
217 return;
218 }
219
220 template<typename T>
UnregisterAudioCapturerCallbackTemplate(napi_env env,napi_value callback,NapiAudioCapturer * napiCapturer,const std::string & cbName,std::function<int32_t (std::shared_ptr<T> callbackPtr,napi_value callback)> removeFunction)221 static void UnregisterAudioCapturerCallbackTemplate(napi_env env, napi_value callback,
222 NapiAudioCapturer *napiCapturer, const std::string &cbName,
223 std::function<int32_t(std::shared_ptr<T> callbackPtr, napi_value callback)> removeFunction)
224 {
225 if (callback != nullptr) {
226 std::shared_ptr<T> cb = nullptr;
227 GetCapturerNapiCallback(callback, cbName, napiCapturer->audioCapturerCallbacks_, &cb);
228 CHECK_AND_RETURN_LOG(cb != nullptr, "CapturerNapiCallback is null");
229 UnregisterAudioCapturerSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
230 return;
231 }
232
233 auto isPresent = [&env, &callback, &cbName, &removeFunction]
234 (std::shared_ptr<NapiAudioCapturerCallbackInner> &iter) {
235 if (!iter->CheckIfTargetCallbackName(cbName)) {
236 return false;
237 }
238 std::shared_ptr<T> cb = std::static_pointer_cast<T>(iter);
239 UnregisterAudioCapturerSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
240 return true;
241 };
242 napiCapturer->audioCapturerCallbacks_.remove_if(isPresent);
243 AUDIO_DEBUG_LOG("UnregisterAudioCapturerCallback success");
244 }
245
Construct(napi_env env,napi_callback_info info)246 napi_value NapiAudioCapturer::Construct(napi_env env, napi_callback_info info)
247 {
248 napi_value result = nullptr;
249 napi_get_undefined(env, &result);
250
251 size_t argCount = ARGS_TWO;
252 napi_value thisVar = nullptr;
253 napi_status status = napi_get_cb_info(env, info, &argCount, nullptr, &thisVar, nullptr);
254 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "failed to napi_get_cb_info");
255
256 unique_ptr<NapiAudioCapturer> napiCapturer = CreateAudioCapturerNativeObject(env);
257 CHECK_AND_RETURN_RET_LOG(napiCapturer != nullptr, result, "failed to CreateAudioCapturerNativeObject");
258 status = napi_wrap(env, thisVar, static_cast<void*>(napiCapturer.get()),
259 NapiAudioCapturer::Destructor, nullptr, nullptr);
260 if (status != napi_ok) {
261 ObjectRefMap<NapiAudioCapturer>::Erase(napiCapturer.get());
262 return result;
263 }
264
265 napiCapturer.release();
266 return thisVar;
267 }
268
CheckContextStatus(std::shared_ptr<AudioCapturerAsyncContext> context)269 bool NapiAudioCapturer::CheckContextStatus(std::shared_ptr<AudioCapturerAsyncContext> context)
270 {
271 CHECK_AND_RETURN_RET_LOG(context != nullptr, false, "CHECK_AND_RETURN_RET_LOG");
272 if (context->native == nullptr) {
273 context->SignError(NAPI_ERR_SYSTEM);
274 return false;
275 }
276 return true;
277 }
278
CheckAudioCapturerStatus(NapiAudioCapturer * napi,std::shared_ptr<AudioCapturerAsyncContext> context)279 bool NapiAudioCapturer::CheckAudioCapturerStatus(NapiAudioCapturer *napi,
280 std::shared_ptr<AudioCapturerAsyncContext> context)
281 {
282 CHECK_AND_RETURN_RET_LOG(napi != nullptr, false, "CHECK_AND_RETURN_RET_LOG");
283 if (napi->audioCapturer_ == nullptr) {
284 context->SignError(NAPI_ERR_SYSTEM);
285 return false;
286 }
287 return true;
288 }
289
GetParamWithSync(const napi_env & env,napi_callback_info info,size_t & argc,napi_value * args)290 NapiAudioCapturer* NapiAudioCapturer::GetParamWithSync(const napi_env &env, napi_callback_info info,
291 size_t &argc, napi_value *args)
292 {
293 napi_status status;
294 NapiAudioCapturer *napiAudioCapturer = nullptr;
295 napi_value jsThis = nullptr;
296
297 status = napi_get_cb_info(env, info, &argc, args, &jsThis, nullptr);
298 CHECK_AND_RETURN_RET_LOG(status == napi_ok && jsThis != nullptr, nullptr,
299 "GetParamWithSync fail to napi_get_cb_info");
300
301 status = napi_unwrap(env, jsThis, (void **)&napiAudioCapturer);
302 CHECK_AND_RETURN_RET_LOG(status == napi_ok, nullptr, "napi_unwrap failed");
303 CHECK_AND_RETURN_RET_LOG((napiAudioCapturer != nullptr) && (napiAudioCapturer->audioCapturer_ != nullptr),
304 napiAudioCapturer, "GetParamWithSync fail to napi_unwrap");
305
306 return napiAudioCapturer;
307 }
308
CreateAudioCapturerWrapper(napi_env env,const AudioCapturerOptions capturerOptions)309 napi_value NapiAudioCapturer::CreateAudioCapturerWrapper(napi_env env, const AudioCapturerOptions capturerOptions)
310 {
311 lock_guard<mutex> lock(createMutex_);
312 napi_value result = nullptr;
313 napi_value constructor = nullptr;
314
315 napi_status status = napi_get_reference_value(env, g_capturerConstructor, &constructor);
316 if (status != napi_ok) {
317 AUDIO_ERR_LOG("napi_get_reference_value failed");
318 goto fail;
319 }
320 if (sCapturerOptions_ != nullptr) {
321 sCapturerOptions_.release();
322 }
323 sCapturerOptions_ = make_unique<AudioCapturerOptions>();
324 CHECK_AND_RETURN_RET_LOG(sCapturerOptions_ != nullptr, result, "sCapturerOptions create failed");
325 *sCapturerOptions_ = capturerOptions;
326 status = napi_new_instance(env, constructor, 0, nullptr, &result);
327 if (status != napi_ok) {
328 AUDIO_ERR_LOG("napi_new_instance failed");
329 goto fail;
330 }
331 return result;
332
333 fail:
334 napi_get_undefined(env, &result);
335 return result;
336 }
337
CreateAudioCapturer(napi_env env,napi_callback_info info)338 napi_value NapiAudioCapturer::CreateAudioCapturer(napi_env env, napi_callback_info info)
339 {
340 auto context = std::make_shared<AudioCapturerAsyncContext>();
341 if (context == nullptr) {
342 AUDIO_ERR_LOG("CreateAudioCapturer failed : no memory");
343 NapiAudioError::ThrowError(env, "CreateAudioCapturer failed : no memory", NAPI_ERR_NO_MEMORY);
344 return NapiParamUtils::GetUndefinedValue(env);
345 }
346
347 auto inputParser = [env, context](size_t argc, napi_value *argv) {
348 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
349 NAPI_ERR_INVALID_PARAM);
350 context->status = NapiParamUtils::GetCapturerOptions(env, &context->capturerOptions, argv[PARAM0]);
351 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "CreateAudioCapturer failed",
352 NAPI_ERR_INVALID_PARAM);
353 };
354 context->GetCbInfo(env, info, inputParser);
355
356 auto complete = [env, context](napi_value &output) {
357 output = CreateAudioCapturerWrapper(env, context->capturerOptions);
358 if (NapiAudioCapturer::isConstructSuccess_ != SUCCESS) {
359 context->SignError(NapiAudioCapturer::isConstructSuccess_);
360 NapiAudioCapturer::isConstructSuccess_ = SUCCESS;
361 }
362 };
363
364 return NapiAsyncWork::Enqueue(env, context, "CreateAudioCapturer", nullptr, complete);
365 }
366
CreateAudioCapturerSync(napi_env env,napi_callback_info info)367 napi_value NapiAudioCapturer::CreateAudioCapturerSync(napi_env env, napi_callback_info info)
368 {
369 size_t argc = ARGS_ONE;
370 napi_value argv[ARGS_ONE] = {};
371 napi_status status = NapiParamUtils::GetParam(env, info, argc, argv);
372 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (argc == ARGS_ONE),
373 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
374 "mandatory parameters are left unspecified"), "invaild param");
375
376 napi_valuetype valueType = napi_undefined;
377 napi_typeof(env, argv[PARAM0], &valueType);
378 CHECK_AND_RETURN_RET_LOG(valueType == napi_object, NapiAudioError::ThrowErrorAndReturn(env,
379 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of options must be number"),
380 "invaild valueType");
381
382 AudioCapturerOptions capturerOptions;
383 CHECK_AND_RETURN_RET_LOG(NapiParamUtils::GetCapturerOptions(env, &capturerOptions, argv[PARAM0]) == napi_ok,
384 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
385 "parameter verification failed: The param of options must be interface AudioCapturerOptions"),
386 "get captureOptions failed");
387
388 return NapiAudioCapturer::CreateAudioCapturerWrapper(env, capturerOptions);
389 }
390
GetCapturerInfo(napi_env env,napi_callback_info info)391 napi_value NapiAudioCapturer::GetCapturerInfo(napi_env env, napi_callback_info info)
392 {
393 auto context = std::make_shared<AudioCapturerAsyncContext>();
394 if (context == nullptr) {
395 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
396 return NapiParamUtils::GetUndefinedValue(env);
397 }
398
399 context->GetCbInfo(env, info);
400
401 auto executor = [context]() {
402 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
403 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
404 ObjectRefMap objectGuard(obj);
405 auto *napiAudioCapturer = objectGuard.GetPtr();
406 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
407 "context object state is error.");
408 context->intValue = napiAudioCapturer->audioCapturer_->GetCapturerInfo(context->capturerInfo);
409 if (context->intValue != SUCCESS) {
410 context->SignError(NAPI_ERR_SYSTEM);
411 }
412 };
413
414 auto complete = [env, context](napi_value &output) {
415 NapiParamUtils::SetCapturerInfo(env, context->capturerInfo, output);
416 };
417
418 return NapiAsyncWork::Enqueue(env, context, "GetCapturerInfo", executor, complete);
419 }
420
GetCapturerInfoSync(napi_env env,napi_callback_info info)421 napi_value NapiAudioCapturer::GetCapturerInfoSync(napi_env env, napi_callback_info info)
422 {
423 napi_value result = nullptr;
424 size_t argc = PARAM0;
425
426 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
427 CHECK_AND_RETURN_RET_LOG(argc == PARAM0, NapiAudioError::ThrowErrorAndReturn(env,
428 NAPI_ERR_INPUT_INVALID), "argsCount invaild");
429
430 AudioCapturerInfo capturerInfo;
431 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
432 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
433 int32_t ret = napiAudioCapturer->audioCapturer_->GetCapturerInfo(capturerInfo);
434
435 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetCapturerInfoSync failure!");
436 NapiParamUtils::SetCapturerInfo(env, capturerInfo, result);
437
438 return result;
439 }
440
GetStreamInfo(napi_env env,napi_callback_info info)441 napi_value NapiAudioCapturer::GetStreamInfo(napi_env env, napi_callback_info info)
442 {
443 auto context = std::make_shared<AudioCapturerAsyncContext>();
444 if (context == nullptr) {
445 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
446 return NapiParamUtils::GetUndefinedValue(env);
447 }
448 context->GetCbInfo(env, info);
449
450 auto executor = [context]() {
451 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
452 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
453 ObjectRefMap objectGuard(obj);
454 auto *napiAudioCapturer = objectGuard.GetPtr();
455 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
456 "context object state is error.");
457 context->intValue = napiAudioCapturer->audioCapturer_->GetStreamInfo(context->streamInfo);
458 if (context->intValue != SUCCESS) {
459 context->SignError(NAPI_ERR_SYSTEM);
460 }
461 };
462
463 auto complete = [env, context](napi_value &output) {
464 NapiParamUtils::SetStreamInfo(env, context->streamInfo, output);
465 };
466
467 return NapiAsyncWork::Enqueue(env, context, "GetStreamInfo", executor, complete);
468 }
469
GetStreamInfoSync(napi_env env,napi_callback_info info)470 napi_value NapiAudioCapturer::GetStreamInfoSync(napi_env env, napi_callback_info info)
471 {
472 napi_value result = nullptr;
473 size_t argc = PARAM0;
474
475 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
476 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
477 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
478
479 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
480 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
481
482 AudioStreamInfo streamInfo;
483 int32_t ret = napiAudioCapturer->audioCapturer_->GetStreamInfo(streamInfo);
484 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetStreamInfo failure!");
485
486 NapiParamUtils::SetStreamInfo(env, streamInfo, result);
487 return result;
488 }
489
Start(napi_env env,napi_callback_info info)490 napi_value NapiAudioCapturer::Start(napi_env env, napi_callback_info info)
491 {
492 auto context = std::make_shared<AudioCapturerAsyncContext>();
493 if (context == nullptr) {
494 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
495 return NapiParamUtils::GetUndefinedValue(env);
496 }
497 context->GetCbInfo(env, info);
498
499 auto executor = [context]() {
500 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
501 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
502 ObjectRefMap objectGuard(obj);
503 auto *napiAudioCapturer = objectGuard.GetPtr();
504 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
505 "context object state is error.");
506 context->isTrue = napiAudioCapturer->audioCapturer_->Start();
507 if (!context->isTrue) {
508 context->SignError(NAPI_ERR_SYSTEM);
509 }
510 };
511
512 auto complete = [env](napi_value &output) {
513 output = NapiParamUtils::GetUndefinedValue(env);
514 };
515 #ifdef FEATURE_HIVIEW_ENABLE
516 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
517 HiviewDFX::ReportXPowerJsStackSysEvent(env, "STREAM_CHANGE", "SRC=Audio");
518 #endif
519 #endif
520 return NapiAsyncWork::Enqueue(env, context, "Start", executor, complete);
521 }
522
ReadFromNative(shared_ptr<AudioCapturerAsyncContext> context)523 napi_status NapiAudioCapturer::ReadFromNative(shared_ptr<AudioCapturerAsyncContext> context)
524 {
525 napi_status status = napi_generic_failure;
526 CHECK_AND_RETURN_RET_LOG(CheckContextStatus(context), napi_generic_failure, "context object state is error.");
527 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
528 ObjectRefMap objectGuard(obj);
529 auto *napiAudioCapturer = objectGuard.GetPtr();
530 CHECK_AND_RETURN_RET_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context), napi_generic_failure,
531 "context object state is error.");
532 uint32_t userSize = context->userSize;
533 uint8_t *buffer = new uint8_t[userSize];
534 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, status, "buffer malloc failed,no memery");
535 int32_t bytesRead = 0;
536 while (static_cast<uint32_t>(bytesRead) < context->userSize) {
537 int32_t len = napiAudioCapturer->audioCapturer_->Read(*(buffer + bytesRead),
538 userSize - bytesRead, context->isBlocking);
539 if (len >= 0) {
540 bytesRead += len;
541 } else {
542 bytesRead = len;
543 break;
544 }
545 }
546 if (bytesRead <= 0) {
547 delete [] buffer;
548 return status;
549 }
550 context->bytesRead = static_cast<size_t>(bytesRead);
551 context->buffer = buffer;
552 status = napi_ok;
553 return status;
554 }
555
SetInputDeviceToAccessory(napi_env env,napi_callback_info info)556 napi_value NapiAudioCapturer::SetInputDeviceToAccessory(napi_env env, napi_callback_info info)
557 {
558 CHECK_AND_RETURN_RET_LOG(PermissionUtil::VerifySelfPermission(),
559 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED), "No system permission");
560 auto context = std::make_shared<AudioCapturerAsyncContext>();
561 if (context == nullptr) {
562 NapiAudioError::ThrowError(env, "SetInputDeviceToAccessory failed : no memory",
563 NAPI_ERR_NO_MEMORY);
564 return NapiParamUtils::GetUndefinedValue(env);
565 }
566
567 context->GetCbInfo(env, info);
568
569 auto executor = [context]() {
570 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
571 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
572 ObjectRefMap objectGuard(obj);
573 auto *napiAudioCapturer = objectGuard.GetPtr();
574 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
575 "context object state is error.");
576 context->intValue = napiAudioCapturer->audioCapturer_->SetInputDevice(DEVICE_TYPE_ACCESSORY);
577 if (context->intValue != SUCCESS) {
578 context->SignError(NAPI_ERR_ILLEGAL_STATE);
579 }
580 };
581
582 auto complete = [env](napi_value &output) {
583 output = NapiParamUtils::GetUndefinedValue(env);
584 };
585 return NapiAsyncWork::Enqueue(env, context, "SetInputDeviceToAccessory", executor, complete);
586 }
587
Read(napi_env env,napi_callback_info info)588 napi_value NapiAudioCapturer::Read(napi_env env, napi_callback_info info)
589 {
590 auto context = std::make_shared<AudioCapturerAsyncContext>();
591 if (context == nullptr) {
592 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
593 return NapiParamUtils::GetUndefinedValue(env);
594 }
595 auto inputParser = [env, context](size_t argc, napi_value *argv) {
596 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
597 NAPI_ERR_INVALID_PARAM);
598 context->status = NapiParamUtils::GetValueUInt32(env, context->userSize, argv[PARAM0]);
599 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "GetValueUInt32 userSize failed",
600 NAPI_ERR_INVALID_PARAM);
601 context->status = NapiParamUtils::GetValueBoolean(env, context->isBlocking, argv[PARAM1]);
602 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "GetValueUInt32 userSize failed",
603 NAPI_ERR_INVALID_PARAM);
604 };
605 context->GetCbInfo(env, info, inputParser);
606
607 auto executor = [context]() {
608 context->status = ReadFromNative(context);
609 if (context->status != napi_ok) {
610 context->SignError(NAPI_ERR_SYSTEM);
611 }
612 };
613
614 auto complete = [env, context](napi_value &output) {
615 NapiParamUtils::CreateArrayBuffer(env, context->bytesRead, context->buffer, output);
616 delete [] context->buffer;
617 context->buffer = nullptr;
618 };
619
620 return NapiAsyncWork::Enqueue(env, context, "Read", executor, complete);
621 }
622
GetAudioTime(napi_env env,napi_callback_info info)623 napi_value NapiAudioCapturer::GetAudioTime(napi_env env, napi_callback_info info)
624 {
625 auto context = std::make_shared<AudioCapturerAsyncContext>();
626 if (context == nullptr) {
627 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
628 return NapiParamUtils::GetUndefinedValue(env);
629 }
630 context->GetCbInfo(env, info);
631
632 auto executor = [context]() {
633 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
634 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
635 ObjectRefMap objectGuard(obj);
636 auto *napiAudioCapturer = objectGuard.GetPtr();
637 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
638 "context object state is error.");
639 Timestamp timestamp;
640 if (napiAudioCapturer->audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC)) {
641 const uint64_t secToNanosecond = 1000000000;
642 context->time = static_cast<uint64_t>(timestamp.time.tv_nsec) +
643 static_cast<uint64_t>(timestamp.time.tv_sec) * secToNanosecond;
644 } else {
645 context->SignError(NAPI_ERR_SYSTEM);
646 }
647 };
648
649 auto complete = [env, context](napi_value &output) {
650 NapiParamUtils::SetValueInt64(env, static_cast<int64_t>(context->time), output);
651 };
652
653 return NapiAsyncWork::Enqueue(env, context, "GetAudioTime", executor, complete);
654 }
655
GetAudioTimeSync(napi_env env,napi_callback_info info)656 napi_value NapiAudioCapturer::GetAudioTimeSync(napi_env env, napi_callback_info info)
657 {
658 napi_value result = nullptr;
659 size_t argc = PARAM0;
660
661 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
662 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
663 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
664
665 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
666 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
667
668 Timestamp timestamp;
669 bool ret = napiAudioCapturer->audioCapturer_->GetAudioTime(timestamp, Timestamp::Timestampbase::MONOTONIC);
670 CHECK_AND_RETURN_RET_LOG(ret, result, "GetAudioTime failure!");
671 const uint64_t secToNanosecond = 1000000000;
672 uint64_t time = static_cast<uint64_t>(timestamp.time.tv_nsec) +
673 static_cast<uint64_t>(timestamp.time.tv_sec) * secToNanosecond;
674
675 NapiParamUtils::SetValueInt64(env, static_cast<int64_t>(time), result);
676 return result;
677 }
678
Stop(napi_env env,napi_callback_info info)679 napi_value NapiAudioCapturer::Stop(napi_env env, napi_callback_info info)
680 {
681 auto context = std::make_shared<AudioCapturerAsyncContext>();
682 if (context == nullptr) {
683 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
684 return NapiParamUtils::GetUndefinedValue(env);
685 }
686 context->GetCbInfo(env, info);
687
688 auto executor = [context]() {
689 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
690 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
691 ObjectRefMap objectGuard(obj);
692 auto *napiAudioCapturer = objectGuard.GetPtr();
693 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
694 "context object state is error.");
695 context->isTrue = napiAudioCapturer->audioCapturer_->Stop();
696 if (!context->isTrue) {
697 context->SignError(NAPI_ERR_SYSTEM);
698 }
699 };
700
701 auto complete = [env](napi_value &output) {
702 output = NapiParamUtils::GetUndefinedValue(env);
703 };
704
705 return NapiAsyncWork::Enqueue(env, context, "Stop", executor, complete);
706 }
707
Release(napi_env env,napi_callback_info info)708 napi_value NapiAudioCapturer::Release(napi_env env, napi_callback_info info)
709 {
710 auto context = std::make_shared<AudioCapturerAsyncContext>();
711 if (context == nullptr) {
712 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
713 return NapiParamUtils::GetUndefinedValue(env);
714 }
715 context->GetCbInfo(env, info);
716
717 auto executor = [context]() {
718 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
719 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
720 ObjectRefMap objectGuard(obj);
721 auto *napiAudioCapturer = objectGuard.GetPtr();
722 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
723 "context object state is error.");
724 context->isTrue = napiAudioCapturer->audioCapturer_->Release();
725 if (!context->isTrue) {
726 context->SignError(NAPI_ERR_SYSTEM);
727 }
728 };
729
730 auto complete = [env](napi_value &output) {
731 output = NapiParamUtils::GetUndefinedValue(env);
732 };
733
734 return NapiAsyncWork::Enqueue(env, context, "Release", executor, complete);
735 }
736
GetBufferSize(napi_env env,napi_callback_info info)737 napi_value NapiAudioCapturer::GetBufferSize(napi_env env, napi_callback_info info)
738 {
739 auto context = std::make_shared<AudioCapturerAsyncContext>();
740 if (context == nullptr) {
741 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
742 return NapiParamUtils::GetUndefinedValue(env);
743 }
744 context->GetCbInfo(env, info);
745
746 auto executor = [context]() {
747 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
748 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
749 ObjectRefMap objectGuard(obj);
750 auto *napiAudioCapturer = objectGuard.GetPtr();
751 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
752 "context object state is error.");
753 context->intValue = napiAudioCapturer->audioCapturer_->GetBufferSize(context->bufferSize);
754 if (context->intValue != SUCCESS) {
755 context->SignError(NAPI_ERR_SYSTEM);
756 }
757 };
758
759 auto complete = [env, context](napi_value &output) {
760 NapiParamUtils::SetValueUInt32(env, context->bufferSize, output);
761 };
762
763 return NapiAsyncWork::Enqueue(env, context, "GetBufferSize", executor, complete);
764 }
765
GetBufferSizeSync(napi_env env,napi_callback_info info)766 napi_value NapiAudioCapturer::GetBufferSizeSync(napi_env env, napi_callback_info info)
767 {
768 napi_value result = nullptr;
769 size_t argc = PARAM0;
770
771 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
772 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
773 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
774
775 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
776 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
777
778 size_t bufferSize;
779 int32_t ret = napiAudioCapturer->audioCapturer_->GetBufferSize(bufferSize);
780 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetBufferSize failure!");
781
782 NapiParamUtils::SetValueUInt32(env, bufferSize, result);
783 return result;
784 }
785
GetAudioStreamId(napi_env env,napi_callback_info info)786 napi_value NapiAudioCapturer::GetAudioStreamId(napi_env env, napi_callback_info info)
787 {
788 auto context = std::make_shared<AudioCapturerAsyncContext>();
789 if (context == nullptr) {
790 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
791 return NapiParamUtils::GetUndefinedValue(env);
792 }
793 context->GetCbInfo(env, info);
794
795 auto executor = [context]() {
796 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
797 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
798 ObjectRefMap objectGuard(obj);
799 auto *napiAudioCapturer = objectGuard.GetPtr();
800 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
801 "context object state is error.");
802 context->intValue = napiAudioCapturer->audioCapturer_->GetAudioStreamId(context->audioStreamId);
803 if (context->intValue == ERR_ILLEGAL_STATE) {
804 context->SignError(NAPI_ERR_ILLEGAL_STATE);
805 } else if (context->intValue == ERR_INVALID_INDEX) {
806 context->SignError(NAPI_ERR_SYSTEM);
807 }
808 };
809
810 auto complete = [env, context](napi_value &output) {
811 NapiParamUtils::SetValueUInt32(env, context->audioStreamId, output);
812 };
813
814 return NapiAsyncWork::Enqueue(env, context, "GetAudioStreamId", executor, complete);
815 }
816
GetAudioStreamIdSync(napi_env env,napi_callback_info info)817 napi_value NapiAudioCapturer::GetAudioStreamIdSync(napi_env env, napi_callback_info info)
818 {
819 napi_value result = nullptr;
820 size_t argc = PARAM0;
821
822 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
823 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
824 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
825
826 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
827 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
828
829 uint32_t audioStreamId;
830 int32_t ret = napiAudioCapturer->audioCapturer_->GetAudioStreamId(audioStreamId);
831 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetAudioStreamId failure!");
832
833 NapiParamUtils::SetValueUInt32(env, audioStreamId, result);
834 return result;
835 }
836
GetCurrentInputDevices(napi_env env,napi_callback_info info)837 napi_value NapiAudioCapturer::GetCurrentInputDevices(napi_env env, napi_callback_info info)
838 {
839 napi_value result = nullptr;
840 size_t argc = PARAM0;
841
842 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
843 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
844 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
845
846 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
847 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
848
849 AudioDeviceDescriptor deviceInfo(AudioDeviceDescriptor::DEVICE_INFO);
850 int32_t ret = napiAudioCapturer->audioCapturer_->GetCurrentInputDevices(deviceInfo);
851 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetCurrentInputDevices failure!");
852
853 NapiParamUtils::SetValueDeviceInfo(env, deviceInfo, result);
854 return result;
855 }
856
GetCurrentAudioCapturerChangeInfo(napi_env env,napi_callback_info info)857 napi_value NapiAudioCapturer::GetCurrentAudioCapturerChangeInfo(napi_env env, napi_callback_info info)
858 {
859 napi_value result = nullptr;
860 size_t argc = PARAM0;
861
862 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
863 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
864 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
865
866 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
867 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
868
869 AudioCapturerChangeInfo capturerInfo;
870 int32_t ret = napiAudioCapturer->audioCapturer_->GetCurrentCapturerChangeInfo(capturerInfo);
871 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetCurrentCapturerChangeInfo failure!");
872
873 NapiParamUtils::SetAudioCapturerChangeInfoDescriptors(env, capturerInfo, result);
874 return result;
875 }
876
GetCurrentMicrophones(napi_env env,napi_callback_info info)877 napi_value NapiAudioCapturer::GetCurrentMicrophones(napi_env env, napi_callback_info info)
878 {
879 napi_value result = nullptr;
880 size_t argc = PARAM0;
881
882 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
883 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
884 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
885
886 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
887 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
888
889 vector<sptr<MicrophoneDescriptor>> micDescs;
890 micDescs = napiAudioCapturer->audioCapturer_->GetCurrentMicrophones();
891
892 NapiParamUtils::SetMicrophoneDescriptors(env, micDescs, result);
893 return result;
894 }
895
GetState(napi_env env,napi_callback_info info)896 napi_value NapiAudioCapturer::GetState(napi_env env, napi_callback_info info)
897 {
898 napi_value result = nullptr;
899 size_t argc = PARAM0;
900
901 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
902 if (argc > PARAM0) {
903 NapiAudioError::ThrowError(env, NAPI_ERR_INPUT_INVALID);
904 napi_get_undefined(env, &result);
905 return result;
906 }
907
908 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
909 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
910
911 int32_t capturerState = napiAudioCapturer->audioCapturer_->GetStatus();
912
913 napi_status status = NapiParamUtils::SetValueInt32(env, capturerState, result);
914 CHECK_AND_RETURN_RET_LOG(status == napi_ok, result, "SetValueInt32 capturerState fail");
915 return result;
916 }
917
GetOverflowCount(napi_env env,napi_callback_info info)918 napi_value NapiAudioCapturer::GetOverflowCount(napi_env env, napi_callback_info info)
919 {
920 auto context = std::make_shared<AudioCapturerAsyncContext>();
921 if (context == nullptr) {
922 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
923 return NapiParamUtils::GetUndefinedValue(env);
924 }
925 context->GetCbInfo(env, info);
926
927 auto executor = [context]() {
928 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
929 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
930 ObjectRefMap objectGuard(obj);
931 auto *napiAudioCapturer = objectGuard.GetPtr();
932 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
933 "context object state is error.");
934 context->overflowCount = napiAudioCapturer->audioCapturer_->GetOverflowCount();
935 };
936
937 auto complete = [env, context](napi_value &output) {
938 NapiParamUtils::SetValueUInt32(env, context->overflowCount, output);
939 };
940
941 return NapiAsyncWork::Enqueue(env, context, "GetOverflowCount", executor, complete);
942 }
943
SetWillMuteWhenInterrupted(napi_env env,napi_callback_info info)944 napi_value NapiAudioCapturer::SetWillMuteWhenInterrupted(napi_env env, napi_callback_info info)
945 {
946 auto context = std::make_shared<AudioCapturerAsyncContext>();
947 if (context == nullptr) {
948 AUDIO_ERR_LOG("failed: no memory");
949 NapiAudioError::ThrowError(env, "SetWillMuteWhenInterrupted failed : no memory", NAPI_ERR_ILLEGAL_STATE);
950 return NapiParamUtils::GetUndefinedValue(env);
951 }
952
953 auto inputParser = [env, context](size_t argc, napi_value *argv) {
954 NAPI_CHECK_ARGS_RETURN_VOID(context, argc >= ARGS_ONE, "invalid arguments",
955 NAPI_ERR_INPUT_INVALID);
956 context->status = NapiParamUtils::GetValueBoolean(env, context->muteWhenInterrupted, argv[PARAM0]);
957 NAPI_CHECK_ARGS_RETURN_VOID(context, context->status == napi_ok, "get muteWhenInterrupted failed",
958 NAPI_ERR_INPUT_INVALID);
959 };
960 context->GetCbInfo(env, info, inputParser);
961
962 auto executor = [context]() {
963 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
964 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
965 ObjectRefMap objectGuard(obj);
966 auto *napiAudioCapturer = objectGuard.GetPtr();
967 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
968 "AudioCapturer state is error.");
969 CHECK_AND_RETURN_LOG(napiAudioCapturer->audioCapturer_ != nullptr, "audioCapturer_ is nullptr");
970 context->intValue = napiAudioCapturer->audioCapturer_->SetInterruptStrategy(context->muteWhenInterrupted ?
971 InterruptStrategy::MUTE : InterruptStrategy::DEFAULT);
972 NAPI_CHECK_ARGS_RETURN_VOID(context, context->intValue == SUCCESS, "SetWillMuteWhenInterrupted failed",
973 NAPI_ERR_SYSTEM);
974 };
975
976 auto complete = [env](napi_value &output) {
977 output = NapiParamUtils::GetUndefinedValue(env);
978 };
979 return NapiAsyncWork::Enqueue(env, context, "SetWillMuteWhenInterrupted", executor, complete);
980 }
981
GetOverflowCountSync(napi_env env,napi_callback_info info)982 napi_value NapiAudioCapturer::GetOverflowCountSync(napi_env env, napi_callback_info info)
983 {
984 napi_value result = nullptr;
985 size_t argc = PARAM0;
986
987 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
988
989 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
990 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
991
992 uint32_t overflowCount = napiAudioCapturer->audioCapturer_->GetOverflowCount();
993
994 NapiParamUtils::SetValueUInt32(env, overflowCount, result);
995 return result;
996 }
997
GetAudioTimestampInfo(napi_env env,napi_callback_info info)998 napi_value NapiAudioCapturer::GetAudioTimestampInfo(napi_env env, napi_callback_info info)
999 {
1000 auto context = std::make_shared<AudioCapturerAsyncContext>();
1001 if (context == nullptr) {
1002 NapiAudioError::ThrowError(env, NAPI_ERR_NO_MEMORY);
1003 return NapiParamUtils::GetUndefinedValue(env);
1004 }
1005 context->GetCbInfo(env, info);
1006
1007 auto executor = [context]() {
1008 CHECK_AND_RETURN_LOG(CheckContextStatus(context), "context object state is error.");
1009 auto obj = reinterpret_cast<NapiAudioCapturer*>(context->native);
1010 ObjectRefMap objectGuard(obj);
1011 auto *napiAudioCapturer = objectGuard.GetPtr();
1012 CHECK_AND_RETURN_LOG(CheckAudioCapturerStatus(napiAudioCapturer, context),
1013 "context object state is error.");
1014 int32_t ret = napiAudioCapturer->audioCapturer_->GetAudioTimestampInfo(context->timeStamp,
1015 Timestamp::Timestampbase::MONOTONIC);
1016 if (ret != SUCCESS) {
1017 context->SignError(NAPI_ERR_SYSTEM);
1018 }
1019 };
1020
1021 auto complete = [env, context](napi_value &output) {
1022 NapiParamUtils::SetTimeStampInfo(env, context->timeStamp, output);
1023 };
1024
1025 return NapiAsyncWork::Enqueue(env, context, "GetAudioTimestampInfo", executor, complete);
1026 }
1027
GetAudioTimestampInfoSync(napi_env env,napi_callback_info info)1028 napi_value NapiAudioCapturer::GetAudioTimestampInfoSync(napi_env env, napi_callback_info info)
1029 {
1030 napi_value result = nullptr;
1031 size_t argc = PARAM0;
1032
1033 auto *napiAudioCapturer = GetParamWithSync(env, info, argc, nullptr);
1034 CHECK_AND_RETURN_RET_LOG(argc == PARAM0,
1035 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID), "invaild param");
1036
1037 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer != nullptr, result, "napiAudioCapturer is nullptr");
1038 CHECK_AND_RETURN_RET_LOG(napiAudioCapturer->audioCapturer_ != nullptr, result, "audioCapturer_ is nullptr");
1039
1040 Timestamp timeStamp;
1041 int32_t ret = napiAudioCapturer->audioCapturer_->GetAudioTimestampInfo(timeStamp,
1042 Timestamp::Timestampbase::MONOTONIC);
1043 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, result, "GetAudioTimestampInfo failure!");
1044 NapiParamUtils::SetTimeStampInfo(env, timeStamp, result);
1045 return result;
1046 }
1047
On(napi_env env,napi_callback_info info)1048 napi_value NapiAudioCapturer::On(napi_env env, napi_callback_info info)
1049 {
1050 const size_t requireArgc = ARGS_TWO;
1051 size_t argc = ARGS_THREE;
1052
1053 napi_value argv[requireArgc + PARAM1] = {nullptr, nullptr, nullptr};
1054 napi_value jsThis = nullptr;
1055 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1056 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
1057 NAPI_ERR_SYSTEM), "napi_get_cb_info failed");
1058 CHECK_AND_RETURN_RET_LOG(argc >= requireArgc, NapiAudioError::ThrowErrorAndReturn(env,
1059 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argc requeset failed");
1060
1061 napi_valuetype eventType = napi_undefined;
1062 napi_typeof(env, argv[PARAM0], &eventType);
1063 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1064 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1065 "eventType invaild");
1066
1067 std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1068 AUDIO_DEBUG_LOG("NapiAudioCapturer: On callbackName: %{public}s", callbackName.c_str());
1069
1070 napi_valuetype handler = napi_undefined;
1071 if (argc == requireArgc) {
1072 napi_typeof(env, argv[PARAM1], &handler);
1073 CHECK_AND_RETURN_RET_LOG(handler == napi_function,
1074 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
1075 "incorrect parameter types: The type of callback must be function"), "handler invaild");
1076 } else {
1077 napi_valuetype paramArg1 = napi_undefined;
1078 napi_typeof(env, argv[PARAM1], ¶mArg1);
1079 napi_valuetype expectedValType = napi_number; // Default. Reset it with 'callbackName' if check, if required.
1080 CHECK_AND_RETURN_RET_LOG(paramArg1 == expectedValType,
1081 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
1082 "incorrect parameter types: The type of frame must be number"), "paramArg1 invaild");
1083
1084 napi_typeof(env, argv[PARAM2], &handler);
1085 CHECK_AND_RETURN_RET_LOG(handler == napi_function,
1086 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID,
1087 "incorrect parameter types: The type of callback must be function"), "handler invaild");
1088 }
1089
1090 return RegisterCallback(env, jsThis, argv, callbackName);
1091 }
1092
RegisterCallback(napi_env env,napi_value jsThis,napi_value * argv,const std::string & cbName)1093 napi_value NapiAudioCapturer::RegisterCallback(napi_env env, napi_value jsThis,
1094 napi_value *argv, const std::string &cbName)
1095 {
1096 NapiAudioCapturer *napiCapturer = nullptr;
1097 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiCapturer));
1098
1099 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
1100 NAPI_ERR_SYSTEM), "napi_unwrap failed");
1101 CHECK_AND_RETURN_RET_LOG(napiCapturer != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1102 NAPI_ERR_NO_MEMORY), "napiCapturer is nullptr");
1103 CHECK_AND_RETURN_RET_LOG(napiCapturer->audioCapturer_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1104 NAPI_ERR_NO_MEMORY), "audioCapturer_ is nullptr");
1105
1106 napi_value result = nullptr;
1107 napi_get_undefined(env, &result);
1108
1109 if (!cbName.compare(STATE_CHANGE_CALLBACK_NAME) ||
1110 !cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME)) {
1111 result = RegisterCapturerCallback(env, argv, cbName, napiCapturer);
1112 } else if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1113 result = RegisterPositionCallback(env, argv, cbName, napiCapturer);
1114 } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1115 result = RegisterPeriodPositionCallback(env, argv, cbName, napiCapturer);
1116 } else if (!cbName.compare(INPUTDEVICE_CHANGE_CALLBACK_NAME)) {
1117 RegisterAudioCapturerDeviceChangeCallback(env, argv, cbName, napiCapturer);
1118 } else if (!cbName.compare(AUDIO_CAPTURER_CHANGE_CALLBACK_NAME)) {
1119 RegisterAudioCapturerInfoChangeCallback(env, argv, cbName, napiCapturer);
1120 } else if (!cbName.compare(READ_DATA_CALLBACK_NAME)) {
1121 RegisterCapturerReadDataCallback(env, argv, cbName, napiCapturer);
1122 } else {
1123 bool unknownCallback = true;
1124 CHECK_AND_RETURN_RET_LOG(!unknownCallback, NapiAudioError::ThrowErrorAndReturn(env,
1125 NAPI_ERROR_INVALID_PARAM,
1126 "parameter verification failed: The param of type is not supported"), "audioCapturer_ is nullptr");
1127 }
1128
1129 return result;
1130 }
1131
RegisterCapturerCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1132 napi_value NapiAudioCapturer::RegisterCapturerCallback(napi_env env, napi_value *argv,
1133 const std::string &cbName, NapiAudioCapturer *napiCapturer)
1134 {
1135 CHECK_AND_RETURN_RET_LOG(napiCapturer->callbackNapi_ != nullptr,
1136 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "napiCapturer is nullptr");
1137
1138 std::shared_ptr<NapiAudioCapturerCallback> cb =
1139 std::static_pointer_cast<NapiAudioCapturerCallback>(napiCapturer->callbackNapi_);
1140 cb->SaveCallbackReference(cbName, argv[PARAM1]);
1141 if (cbName == INTERRUPT_CALLBACK_NAME || cbName == AUDIO_INTERRUPT_CALLBACK_NAME) {
1142 if (!cb->GetInterruptTsfnFlag()) {
1143 cb->CreateInterruptTsfn(env);
1144 }
1145 } else if (cbName == STATE_CHANGE_CALLBACK_NAME) {
1146 if (!cb->GetStateChangeTsfnFlag()) {
1147 cb->CreateStateChangeTsfn(env);
1148 }
1149 }
1150
1151 if (!cbName.compare(STATE_CHANGE_CALLBACK_NAME)) {
1152 CapturerState state = napiCapturer->audioCapturer_->GetStatus();
1153 if (state == CAPTURER_PREPARED) {
1154 napiCapturer->callbackNapi_->OnStateChange(state);
1155 }
1156 }
1157
1158 napi_value result = nullptr;
1159 napi_get_undefined(env, &result);
1160 return result;
1161 }
1162
RegisterPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1163 napi_value NapiAudioCapturer::RegisterPositionCallback(napi_env env, napi_value *argv,
1164 const std::string &cbName, NapiAudioCapturer *napiCapturer)
1165 {
1166 int64_t markPosition = 0;
1167 NapiParamUtils::GetValueInt64(env, markPosition, argv[PARAM1]);
1168
1169 AUDIO_INFO_LOG("NapiAudioCapturer:RegisterPositionCallback start!");
1170 if (markPosition > 0) {
1171 napiCapturer->positionCbNapi_ = std::make_shared<NapiCapturerPositionCallback>(env);
1172 CHECK_AND_RETURN_RET_LOG(napiCapturer->positionCbNapi_ != nullptr,
1173 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "positionCbNapi_ is nullptr");
1174 int32_t ret = napiCapturer->audioCapturer_->SetCapturerPositionCallback(markPosition,
1175 napiCapturer->positionCbNapi_);
1176 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS,
1177 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
1178 "SetCapturerPositionCallback failed");
1179
1180 std::shared_ptr<NapiCapturerPositionCallback> cb =
1181 std::static_pointer_cast<NapiCapturerPositionCallback>(napiCapturer->positionCbNapi_);
1182 cb->SaveCallbackReference(cbName, argv[PARAM2]);
1183 if (!cb->GetCapturePositionFlag()) {
1184 cb->CreateCapturePositionTsfn(env);
1185 }
1186 } else {
1187 AUDIO_ERR_LOG("NapiAudioCapturer: Mark Position value not supported!!");
1188 CHECK_AND_RETURN_RET_LOG(false, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
1189 "parameter verification failed: The param of frame is not supported"), "invailed callback");
1190 }
1191
1192 napi_value result = nullptr;
1193 napi_get_undefined(env, &result);
1194 return result;
1195 }
1196
RegisterPeriodPositionCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1197 napi_value NapiAudioCapturer::RegisterPeriodPositionCallback(napi_env env, napi_value *argv, const std::string &cbName,
1198 NapiAudioCapturer *napiCapturer)
1199 {
1200 int64_t frameCount = 0;
1201 napi_get_value_int64(env, argv[PARAM1], &frameCount);
1202
1203 CHECK_AND_RETURN_RET_LOG(frameCount > 0, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_INVALID_PARAM,
1204 "parameter verification failed: The param of frame is not supported"), "frameCount value not supported");
1205
1206 CHECK_AND_RETURN_RET_LOG(napiCapturer->periodPositionCbNapi_ == nullptr,
1207 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_ILLEGAL_STATE),
1208 "periodReach already subscribed.");
1209
1210 std::shared_ptr<NapiCapturerPeriodPositionCallback> cb = std::make_shared<NapiCapturerPeriodPositionCallback>(env);
1211 CHECK_AND_RETURN_RET_LOG(cb != nullptr,
1212 NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_NO_MEMORY), "periodPositionCbNapi_ id nullptr");
1213 napiCapturer->periodPositionCbNapi_ = cb;
1214
1215 int32_t ret = napiCapturer->audioCapturer_->SetCapturerPeriodPositionCallback(frameCount, cb);
1216 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, NapiAudioError::ThrowErrorAndReturn(env, NAPI_ERR_SYSTEM),
1217 "SetCapturerPeriodPositionCallback failed");
1218
1219 cb->SaveCallbackReference(cbName, argv[PARAM2]);
1220 cb->CreatePeriodPositionTsfn(env);
1221
1222 napi_value result = nullptr;
1223 napi_get_undefined(env, &result);
1224 return result;
1225 }
1226
RegisterAudioCapturerDeviceChangeCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1227 void NapiAudioCapturer::RegisterAudioCapturerDeviceChangeCallback(napi_env env, napi_value *argv,
1228 const std::string &cbName, NapiAudioCapturer *napiCapturer)
1229 {
1230 std::shared_ptr<NapiAudioCapturerDeviceChangeCallback> cb = nullptr;
1231 GetCapturerNapiCallback(argv[PARAM1], cbName, napiCapturer->audioCapturerCallbacks_, &cb);
1232 CHECK_AND_RETURN_LOG(cb == nullptr, "Do not register same capturer device callback!");
1233
1234 cb = std::make_shared<NapiAudioCapturerDeviceChangeCallback>(env);
1235 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1236
1237 cb->SaveCallbackReference(cbName, argv[PARAM1]);
1238 cb->CreateCaptureDeviceChangeTsfn(env);
1239 int32_t ret =
1240 napiCapturer->audioCapturer_->SetAudioCapturerDeviceChangeCallback(cb);
1241 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Registering of capturer device change callback failed");
1242
1243 napiCapturer->audioCapturerCallbacks_.push_back(cb);
1244
1245 AUDIO_DEBUG_LOG("RegisterAudioCapturerDeviceChangeCallback is successful");
1246 }
1247
RegisterAudioCapturerInfoChangeCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1248 void NapiAudioCapturer::RegisterAudioCapturerInfoChangeCallback(napi_env env, napi_value *argv,
1249 const std::string &cbName, NapiAudioCapturer *napiCapturer)
1250 {
1251 std::shared_ptr<NapiAudioCapturerInfoChangeCallback> cb = nullptr;
1252 GetCapturerNapiCallback(argv[PARAM1], cbName, napiCapturer->audioCapturerCallbacks_, &cb);
1253 CHECK_AND_RETURN_LOG(cb == nullptr, "Do not register same capturer info change callback!");
1254 cb = std::make_shared<NapiAudioCapturerInfoChangeCallback>(env);
1255
1256 CHECK_AND_RETURN_LOG(cb != nullptr, "Memory allocation failed!!");
1257
1258 cb->SaveCallbackReference(cbName, argv[PARAM1]);
1259 cb->CreateCaptureInfoChangeTsfn(env);
1260 int32_t ret =
1261 napiCapturer->audioCapturer_->SetAudioCapturerInfoChangeCallback(cb);
1262 CHECK_AND_RETURN_LOG(ret == SUCCESS, "Registering of capturer info change callback failed");
1263
1264 napiCapturer->audioCapturerCallbacks_.push_back(cb);
1265
1266 AUDIO_DEBUG_LOG("RegisterAudioCapturerInfoChangeCallback is successful");
1267 }
1268
RegisterCapturerReadDataCallback(napi_env env,napi_value * argv,const std::string & cbName,NapiAudioCapturer * napiCapturer)1269 void NapiAudioCapturer::RegisterCapturerReadDataCallback(napi_env env, napi_value *argv, const std::string &cbName,
1270 NapiAudioCapturer *napiCapturer)
1271 {
1272 CHECK_AND_RETURN_LOG(napiCapturer->capturerReadDataCallbackNapi_ == nullptr, "readData already subscribed.");
1273
1274 napiCapturer->capturerReadDataCallbackNapi_ = std::make_shared<NapiCapturerReadDataCallback>(env, napiCapturer);
1275 napiCapturer->audioCapturer_->SetCaptureMode(CAPTURE_MODE_CALLBACK);
1276 CHECK_AND_RETURN_LOG(napiCapturer->capturerReadDataCallbackNapi_ != nullptr, "readDataNapi_ is nullptr");
1277 int32_t ret = napiCapturer->audioCapturer_->SetCapturerReadCallback(napiCapturer->capturerReadDataCallbackNapi_);
1278 CHECK_AND_RETURN_LOG(ret == SUCCESS, "SetCapturerCallback failed");
1279 std::shared_ptr<NapiCapturerReadDataCallback> cb =
1280 std::static_pointer_cast<NapiCapturerReadDataCallback>(napiCapturer->capturerReadDataCallbackNapi_);
1281 cb->AddCallbackReference(cbName, argv[PARAM1]);
1282 cb->CreateReadDataTsfn(env);
1283
1284 AUDIO_INFO_LOG("Register Callback is successful");
1285 }
1286
Off(napi_env env,napi_callback_info info)1287 napi_value NapiAudioCapturer::Off(napi_env env, napi_callback_info info)
1288 {
1289 const size_t minArgCount = ARGS_ONE;
1290 size_t argc = ARGS_TWO;
1291
1292 napi_value argv[minArgCount + 1] = {nullptr, nullptr};
1293 napi_value jsThis = nullptr;
1294 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
1295 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
1296 NAPI_ERR_SYSTEM), "napi_get_cb_info failed");
1297 CHECK_AND_RETURN_RET_LOG(argc >= minArgCount, NapiAudioError::ThrowErrorAndReturn(env,
1298 NAPI_ERR_INPUT_INVALID, "mandatory parameters are left unspecified"), "argc invaild");
1299
1300 napi_valuetype eventType = napi_undefined;
1301 napi_typeof(env, argv[PARAM0], &eventType);
1302 CHECK_AND_RETURN_RET_LOG(eventType == napi_string, NapiAudioError::ThrowErrorAndReturn(env,
1303 NAPI_ERR_INPUT_INVALID, "incorrect parameter types: The type of eventType must be string"),
1304 "eventType invaild");
1305
1306 std::string callbackName = NapiParamUtils::GetStringArgument(env, argv[PARAM0]);
1307 AUDIO_DEBUG_LOG("NapiAudioCapturer: Off callbackName: %{public}s", callbackName.c_str());
1308
1309 return UnregisterCallback(env, jsThis, argc, argv, callbackName);
1310 }
1311
UnregisterCallback(napi_env env,napi_value jsThis,size_t argc,napi_value * argv,const std::string & cbName)1312 napi_value NapiAudioCapturer::UnregisterCallback(napi_env env, napi_value jsThis, size_t argc, napi_value *argv,
1313 const std::string &cbName)
1314 {
1315 NapiAudioCapturer *napiCapturer = nullptr;
1316 napi_status status = napi_unwrap(env, jsThis, reinterpret_cast<void **>(&napiCapturer));
1317 CHECK_AND_RETURN_RET_LOG(status == napi_ok, NapiAudioError::ThrowErrorAndReturn(env,
1318 NAPI_ERR_SYSTEM), "napi_unwrap failed");
1319 CHECK_AND_RETURN_RET_LOG(napiCapturer != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1320 NAPI_ERR_NO_MEMORY), "napiCapturer is nullptr");
1321 CHECK_AND_RETURN_RET_LOG(napiCapturer->audioCapturer_ != nullptr, NapiAudioError::ThrowErrorAndReturn(env,
1322 NAPI_ERR_NO_MEMORY), "audioCapturer_ is nullptr");
1323
1324 if (!cbName.compare(MARK_REACH_CALLBACK_NAME)) {
1325 UnregisterCapturerPositionCallback(env, argc, cbName, argv, napiCapturer);
1326 } else if (!cbName.compare(PERIOD_REACH_CALLBACK_NAME)) {
1327 UnregisterCapturerPeriodPositionCallback(env, argc, cbName, argv, napiCapturer);
1328 } else if (!cbName.compare(STATE_CHANGE_CALLBACK_NAME) ||
1329 !cbName.compare(AUDIO_INTERRUPT_CALLBACK_NAME)) {
1330 UnregisterCapturerCallback(env, argc, cbName, argv, napiCapturer);
1331 } else if (!cbName.compare(INPUTDEVICE_CHANGE_CALLBACK_NAME)) {
1332 UnregisterAudioCapturerDeviceChangeCallback(env, argc, cbName, argv, napiCapturer);
1333 } else if (!cbName.compare(AUDIO_CAPTURER_CHANGE_CALLBACK_NAME)) {
1334 UnregisterAudioCapturerInfoChangeCallback(env, argc, cbName, argv, napiCapturer);
1335 } else if (!cbName.compare(READ_DATA_CALLBACK_NAME)) {
1336 UnregisterCapturerReadDataCallback(env, argc, argv, napiCapturer);
1337 } else {
1338 bool unknownCallback = true;
1339 CHECK_AND_RETURN_RET_LOG(!unknownCallback, NapiAudioError::ThrowErrorAndReturn(env,
1340 NAPI_ERR_INVALID_PARAM,
1341 "parameter verification failed: The param of type is not supported"),
1342 "NAPI_ERR_UNSUPPORTED cbName");
1343 }
1344
1345 napi_value result = nullptr;
1346 napi_get_undefined(env, &result);
1347 return result;
1348 }
1349
UnregisterCapturerPeriodPositionCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioCapturer * napiCapturer)1350 void NapiAudioCapturer::UnregisterCapturerPeriodPositionCallback(napi_env env, size_t argc,
1351 const std::string &cbName, napi_value *argv, NapiAudioCapturer *napiCapturer)
1352 {
1353 CHECK_AND_RETURN_LOG(napiCapturer->periodPositionCbNapi_ != nullptr, "capturerCallbackNapi is nullptr");
1354
1355 std::shared_ptr<NapiCapturerPeriodPositionCallback> cb =
1356 std::static_pointer_cast<NapiCapturerPeriodPositionCallback>(napiCapturer->periodPositionCbNapi_);
1357 std::function<int32_t(std::shared_ptr<NapiCapturerPeriodPositionCallback> callbackPtr,
1358 napi_value callback)> removeFunction =
1359 [&napiCapturer] (std::shared_ptr<NapiCapturerPeriodPositionCallback> callbackPtr, napi_value callback) {
1360 napiCapturer->audioCapturer_->UnsetCapturerPeriodPositionCallback();
1361 napiCapturer->periodPositionCbNapi_ = nullptr;
1362 return SUCCESS;
1363 };
1364 auto callback = GetCallback(argc, argv);
1365 UnregisterAudioCapturerSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
1366 AUDIO_INFO_LOG("UnregisterCapturerPeriodPositionCallback is successful");
1367 }
1368
UnregisterCapturerPositionCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioCapturer * napiCapturer)1369 void NapiAudioCapturer::UnregisterCapturerPositionCallback(napi_env env, size_t argc,
1370 const std::string &cbName, napi_value *argv, NapiAudioCapturer *napiCapturer)
1371 {
1372 CHECK_AND_RETURN_LOG(napiCapturer->positionCbNapi_ != nullptr, "capturerCallbackNapi is nullptr");
1373
1374 std::shared_ptr<NapiCapturerPositionCallback> cb =
1375 std::static_pointer_cast<NapiCapturerPositionCallback>(napiCapturer->positionCbNapi_);
1376 std::function<int32_t(std::shared_ptr<NapiCapturerPositionCallback> callbackPtr,
1377 napi_value callback)> removeFunction =
1378 [&napiCapturer] (std::shared_ptr<NapiCapturerPositionCallback> callbackPtr, napi_value callback) {
1379 napiCapturer->audioCapturer_->UnsetCapturerPositionCallback();
1380 napiCapturer->positionCbNapi_ = nullptr;
1381 return SUCCESS;
1382 };
1383 auto callback = GetCallback(argc, argv);
1384 UnregisterAudioCapturerSingletonCallbackTemplate(env, callback, cbName, cb, removeFunction);
1385 AUDIO_INFO_LOG("UnregisterCapturerPositionCallback is successful");
1386 }
1387
UnregisterCapturerCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioCapturer * napiCapturer)1388 void NapiAudioCapturer::UnregisterCapturerCallback(napi_env env, size_t argc,
1389 const std::string &cbName, napi_value *argv, NapiAudioCapturer *napiCapturer)
1390 {
1391 CHECK_AND_RETURN_LOG(napiCapturer->callbackNapi_ != nullptr, "capturerCallbackNapi is nullptr");
1392 std::shared_ptr<NapiAudioCapturerCallback> cb =
1393 std::static_pointer_cast<NapiAudioCapturerCallback>(napiCapturer->callbackNapi_);
1394 auto callback = GetCallback(argc, argv);
1395 UnregisterAudioCapturerSingletonCallbackTemplate(env, callback, cbName, cb);
1396 AUDIO_INFO_LOG("Unregister CapturerCallback is successful");
1397 }
1398
UnregisterAudioCapturerDeviceChangeCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioCapturer * napiCapturer)1399 void NapiAudioCapturer::UnregisterAudioCapturerDeviceChangeCallback(napi_env env, size_t argc,
1400 const std::string &cbName, napi_value *argv, NapiAudioCapturer *napiCapturer)
1401 {
1402 std::function<int32_t(std::shared_ptr<NapiAudioCapturerDeviceChangeCallback> callbackptr,
1403 napi_value callback)> removeFunction =
1404 [&napiCapturer] (std::shared_ptr<NapiAudioCapturerDeviceChangeCallback> callbackPtr, napi_value callback) {
1405 return napiCapturer->audioCapturer_->RemoveAudioCapturerDeviceChangeCallback(callbackPtr);
1406 };
1407 auto callback = GetCallback(argc, argv);
1408 UnregisterAudioCapturerCallbackTemplate(env, callback, napiCapturer, cbName, removeFunction);
1409
1410 AUDIO_INFO_LOG("UnregisterCapturerDeviceChangeCallback is successful");
1411 }
1412
UnregisterAudioCapturerInfoChangeCallback(napi_env env,size_t argc,const std::string & cbName,napi_value * argv,NapiAudioCapturer * napiCapturer)1413 void NapiAudioCapturer::UnregisterAudioCapturerInfoChangeCallback(napi_env env, size_t argc,
1414 const std::string &cbName, napi_value *argv, NapiAudioCapturer *napiCapturer)
1415 {
1416 std::function<int32_t(std::shared_ptr<NapiAudioCapturerInfoChangeCallback> callbackPtr,
1417 napi_value callback)> removeFunction =
1418 [&napiCapturer] (std::shared_ptr<NapiAudioCapturerInfoChangeCallback> callbackPtr, napi_value callback) {
1419 return napiCapturer->audioCapturer_->RemoveAudioCapturerInfoChangeCallback(callbackPtr);
1420 };
1421 auto callback = GetCallback(argc, argv);
1422 UnregisterAudioCapturerCallbackTemplate(env, callback, napiCapturer, cbName, removeFunction);
1423 AUDIO_DEBUG_LOG("UnregisterAudioCapturerInfoChangeCallback is successful");
1424 }
1425
UnregisterCapturerReadDataCallback(napi_env env,size_t argc,napi_value * argv,NapiAudioCapturer * napiCapturer)1426 void NapiAudioCapturer::UnregisterCapturerReadDataCallback(napi_env env, size_t argc, napi_value *argv,
1427 NapiAudioCapturer *napiCapturer)
1428 {
1429 napi_value callback = nullptr;
1430
1431 if (argc == ARGS_TWO) {
1432 callback = argv[PARAM1];
1433 }
1434 CHECK_AND_RETURN_LOG(napiCapturer->capturerReadDataCallbackNapi_ != nullptr,
1435 "napiCapturerReadDataCallback is nullptr, return");
1436
1437 std::shared_ptr<NapiCapturerReadDataCallback> cb =
1438 std::static_pointer_cast<NapiCapturerReadDataCallback>(napiCapturer->capturerReadDataCallbackNapi_);
1439 cb->RemoveCallbackReference(env, callback);
1440
1441 AUDIO_INFO_LOG("Unregister Callback is successful");
1442 }
1443 } // namespace AudioStandard
1444 } // namespace OHOS
1445