• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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], &paramArg1);
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